First of all, edit your_app_settings/settings.py
and add:
INSTALLED_APPS = [
'django.forms', # to let django discover the built-in widgets
...
]
FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'
TEMPLATES = [
{
# /stable/topics/templates/#django.template.backends.jinja2.Jinja2
'BACKEND': 'django.template.backends.jinja2.Jinja2',
'DIRS': [
'your_app/widgets',
django.__path__[0] + '/forms/jinja2',
],
'APP_DIRS': True,
'OPTIONS': {
'environment': 'your_app_settings.jinja2.environment',
'context_processors': [
'django.template.context_processors.debug',
],
},
},
...
]
Then create a directory your_app/widgets/your_app
and place the files you want to use inside it, for example bulma_select.html
:
<div class="select">{% include "django/forms/widgets/select.html" %}</div>
This widget simply adds a div with a select
class around the select widget, so that bulma (https://bulma.io) renders select dropdowns with the correct styling; it then delegates the normal select rendering to the jinja2 select.html
widget template.
Eventually, in your_app/forms.py
you can create a specific widget class:
class BulmaCSSSelectWidget(forms.widgets.Select):
template_name = "your_app/bulma_select.html"
or, if you want to edit a widget "on the fly" e.g., inside __init__
, you can use:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields:
widget = self.fields[field].widget
# No idea why the Textarea widget doesn't implement .input_type:
# /en/stable/_modules/django/forms/widgets/#Textarea
if isinstance(widget, forms.widgets.Textarea):
widget.attrs.update({"class": "textarea"})
elif widget.input_type in ("text", "password", "date", "number"):
widget.attrs.update({"class": "input"})
elif widget.input_type == "select":
widget.template_name = "your_app/bulma_select.html" # this
...
By wrapping this __init__
into a class, it can be applied to all forms/modelforms, using inheritance, without touching the single fields widget.