I'm new to Django (and Python), and am trying to figure out how to conditionalize certain aspects of form validation. In this case, there's a HTML interface to the application where the user can choose a date and a time from widgets. The clean
method on the form object takes the values of the time and date fields and turns them back into a datetime
.
In addition to the HTML interface, there's also an iPhone client making calls into the application, and I'd like to pass a UNIX timestamp-style time value in.
My form code looks like this:
class FooForm(forms.ModelForm):
foo_date = forms.CharField(required=True, widget=forms.RadioSelect(choices=DATE_CHOICES))
foo_time = forms.CharField(required=True, widget=SelectTimeWidget())
foo_timestamp = forms.CharField(required=False)
How do I make foo_date
and foo_time
required unless foo_timestamp
is provided?
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.
Django provides built-in methods to validate form data automatically. Django forms submit only if it contains CSRF tokens. It uses uses a clean and easy approach to validate data. The is_valid() method is used to perform validation for each field of the form, it is defined in Django Form class.
If yes try to disable this behavior, set the novalidate attribute on the form tag As <form action="{% url 'new_page' %}", method="POST" novalidate> in your html file.
The clean() method on a Field subclass is responsible for running to_python() , validate() , and run_validators() in the correct order and propagating their errors. If, at any time, any of the methods raise ValidationError , the validation stops and that error is raised.
This is done with the clean
method on the form. You need to set foo_date
and foo_time
to required=False
, though, because clean
is only called after every field has been validated (see also the documentation).
class FooForm(forms.Form)
# your field definitions
def clean(self):
data = self.cleaned_data
if data.get('foo_timestamp', None) or (data.get('foo_date', None) and data.get('foo_time', None)):
return data
else:
raise forms.ValidationError('Provide either a date and time or a timestamp')
I found myself needing a "standard" way to do this, as my forms have several conditionally required fields. So I created a superclass with the following method:
def validate_required_field(self, cleaned_data, field_name, message="This field is required"):
if(field_name in cleaned_data and cleaned_data[field_name] is None):
self._errors[field_name] = self.error_class([message])
del cleaned_data[field_name]
And then in my form's clean method I have:
def clean(self):
cleaned_data = super(FormClass, self).clean()
if(condition):
self.validate_required_field(cleaned_data, 'field_name')
It's worked perfectly for me so far.
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