Add a CSS class to the DIVs of the fields of all forms

Hi!

I need to add a CSS class to the DIVs of the fields of all my forms.
The field.css_classes here seems made for this:

And, if I understand right, its implementation is here:

But I couldn’t find an easy way to add the CSS class.

I even tried overriding the template (something I would like to avoid, because it can make incompatible with future updates), creating a templates/django/forms/div.html in my app, but even after restarting the dev server it keept using the original template.

I endeded with a not so pretty patch like this (executed from my settings.py file):

from django.forms.boundfield import BoundField


def apply_patches():
    if not getattr(BoundField.css_classes, 'patched', False):
        unpatched = BoundField.css_classes

        def css_classes(self, extra_classes=None):
            return unpatched(self, ['form-field'] + (extra_classes or []))

        BoundField.css_classes = css_classes
        BoundField.css_classes.patched = True

Is there a better way of doing it?

Did you remember to change the TemplatesSetting when doing this?
See Overriding built-in widget templates, TemplatesSetting and The low-level render API. (Also, I stored this in my project’s templates directory, not the app’s templates directory. Putting this in the app’s directory makes it subject to the search order of apps.)

When I do this, my div.html is used for the rendering process.

Thanks for the response!

So is there no way to customize the field.css_classes value, even if it has an extra_classes parameter? Is the recommended way to overwrite the whole template?

Sorry - I was not attempting to answer that portion of your question. But from what I’m seeing - no. There does not appear to be a “global default” that would apply to every field being rendered. I know you can change this on a per-field basis - but then you’d need to add this to every field definition on every form, and that’s not my impression of what you’re looking for.

Side note: Actually, I would hold the opinion that overriding a template is less risky than modifying code. It’s not like there’s going to be other code dependent upon the behavior of that template.

But even that may not be necessary. As I’m looking through the source trying to find an answer, I see where BaseForm has a template_name_div attribute - if you need to do this on a by-form basis, you could set that attribute for each form individually. If you want this for every form, you could create a Form subclass that has that attribute defined, then inherit all your forms from it.

1 Like

Thanks for the research! I just wanted to make sure there wasn’t an obvious simple way of doing it.