In my settings.py I have set
FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'
now in can add my own templates in:
<project>/templates/django/forms/widgets/
or
<app>/templates/django/forms/widgets/
this works great! However, what I can't find is where do I override the default html (form) label?
class TestForm(forms.Form):
first_name = forms.CharField(label="First name", max_length=50)
last_name = forms.CharField(label="Last name")
nick_name = forms.CharField(required=False)
The above form would render the labels like this:
<label for="id_first_name">First name:</label>
I want to render the label differently. So, I thought it would easy as adding a html label template: templates/django/forms/widgets/label.html
This doesn't work. Was going through the Django docs, but I can't find how to do this for labels. Apparently a label is not a widget.
https://docs.djangoproject.com/en/1.11/ref/forms/widgets/#built-in-widgets
My question, where/how do I change the default label?
Here is a working solution (tested on Django 3.1) :
Create a child class of Django's Form, and set LABEL_TEMPLATE
to the template your want.
myapp/base_form.py
from django import forms
from django.forms.utils import flatatt
from django.utils.html import conditional_escape, format_html
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
LABEL_TEMPLATE = '<p{}>{}</p>'
class CustomLabelBoundField(forms.boundfield.BoundField):
def label_tag(self, contents=None, attrs=None, label_suffix=None):
"""
Wrap the given contents in a <label>, if the field has an ID attribute.
contents should be mark_safe'd to avoid HTML escaping. If contents
aren't given, use the field's HTML-escaped label.
If attrs are given, use them as HTML attributes on the <label> tag.
label_suffix overrides the form's label_suffix.
"""
contents = contents or self.label
if label_suffix is None:
label_suffix = (self.field.label_suffix if self.field.label_suffix is not None
else self.form.label_suffix)
# Only add the suffix if the label does not end in punctuation.
# Translators: If found as last label character, these punctuation
# characters will prevent the default label_suffix to be appended to the label
if label_suffix and contents and contents[-1] not in _(':?.!'):
contents = format_html('{}{}', contents, label_suffix)
widget = self.field.widget
id_ = widget.attrs.get('id') or self.auto_id
if id_:
id_for_label = widget.id_for_label(id_)
if id_for_label:
attrs = {**(attrs or {}), 'for': id_for_label}
if self.field.required and hasattr(self.form, 'required_css_class'):
attrs = attrs or {}
if 'class' in attrs:
attrs['class'] += ' ' + self.form.required_css_class
else:
attrs['class'] = self.form.required_css_class
attrs = flatatt(attrs) if attrs else ''
contents = format_html(LABEL_TEMPLATE, attrs, contents)
else:
contents = conditional_escape(contents)
return mark_safe(contents)
def get_bound_field(field, form, field_name):
"""
Return a BoundField instance that will be used when accessing the form
field in a template.
"""
return CustomLabelBoundField(form, field, field_name)
class CustomLabelForm(forms.Form):
def __getitem__(self, name):
"""Return a BoundField with the given name."""
try:
field = self.fields[name]
except KeyError:
raise KeyError(
"Key '%s' not found in '%s'. Choices are: %s." % (
name,
self.__class__.__name__,
', '.join(sorted(self.fields)),
)
)
if name not in self._bound_fields_cache:
self._bound_fields_cache[name] = get_bound_field(field, self, name)
return self._bound_fields_cache[name]
And inherit your form from CustomLabelForm
:
myapp/forms.py
from django import forms
from myapp.base_form import CustomLabelForm
class TestForm(CustomLabelForm):
first_name = forms.CharField(label="First name", max_length=50)
last_name = forms.CharField(label="Last name")
nick_name = forms.CharField(required=False)
This produces <p for="id_first_name">First name:</p>
You could override __init__()
method of the form:
def __init__(self, *args, **kwargs):
self.fields['field_name'].label = 'Your new label here'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With