I have this form field:
email = forms.EmailField(
required=True,
max_length=100,
)
It has the required attribute, but in the html it is not adding the html attribute required
. In fact it's not even using email
as the field type, it's using text
... though it appears to get max_length just fine.
Actual:
<input id="id_email" type="text" name="email" maxlength="100">
Expected:
<input id="id_email" type="email" name="email" maxlength="100" required="true">
How can I get Django to use the correct attributes in html forms?
Let's try to use required via Django Web application we created, visit http://localhost:8000/ and try to input the value based on option or validation applied on the Field. Hit submit. Hence Field is accepting the form even without any data in the geeks_field. This makes required=False implemented successfully.
The is_valid() method is used to perform validation for each field of the form, it is defined in Django Form class. It returns True if data is valid and place all data into a cleaned_data attribute.
With Django forms, the standard forms HTML is auto-generated for you and you have to write code for only where you want to customize the form. Django forms also handle form validation for you, and you can override with self-written code only when you want some special case validation.
form. cleaned_data returns a dictionary of validated form input fields and their values, where string primary keys are returned as objects. form. data returns a dictionary of un-validated form input fields and their values in string format (i.e. not objects).
Django form elements are written against <input />
as it exists in HTML 4, where type="text"
was the correct option for e-mail addresses. There was also no required="true"
.
If you want custom HTML attributes, you need the attrs
keyword argument to the widget. It would look something like this:
email = forms.EmailField(
max_length=100,
required=True,
widget=forms.TextInput(attrs={ 'required': 'true' }),
)
You can check out more documentation about widgets here. Discussion of attrs
is near the bottom of that page.
Regarding type="email"
, you might be able to send that to your attrs
dictionary and Django will intelligently override its default. If that isn't the result you get, then your route is to subclass forms.TextInput
and then pass it to the widget
keyword argument.
Combining Daniel and Daniel answers, I usually use this mixin for my forms:
from django.contrib.admin.widgets import AdminFileWidget
from django.forms.widgets import HiddenInput, FileInput
class HTML5RequiredMixin(object):
def __init__(self, *args, **kwargs):
super(HTML5RequiredMixin, self).__init__(*args, **kwargs)
for field in self.fields:
if (self.fields[field].required and
type(self.fields[field].widget) not in
(AdminFileWidget, HiddenInput, FileInput) and
'__prefix__' not in self.fields[field].widget.attrs):
self.fields[field].widget.attrs['required'] = 'required'
if self.fields[field].label:
self.fields[field].label += ' *'
So when i have to create a new form or modelform i just use:
class NewForm(HTML5RequiredMixin, forms.Form):
...
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