Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django - how to process/clean a field before validation

I have a form that needs to be validated only after it has been cleaned.

What happens when you run form.is_valid() ? Is the form cleaned and then that cleaned version of the form validated?

The behaviour I'm getting at the moment, is that if my field does not pass validation before cleaning, even if cleaning would make it pass, is_valid() returns False.

Am I doing something wrong?

Code:

# View class ContactForm(forms.Form):     message = forms.CharField(widget=forms.Textarea, max_length=5)      def clean_message(self):         message = self.cleaned_data['message']         return message.replace('a', '') # remove all "a"s from message  def contact(request):     if request.method == 'POST':         if form.is_valid():             return HttpResponseRedirect('/contact/on_success/')         else:             return HttpResponseRedirect('/contact/on_failure/') 

I want form.is_valid() to return True if the message has less than 5 characters NOT including a!

Is it possible to run clean_<fieldname>() after to_python() but before run_validators()? Or should I be doing this some other way?

like image 271
Acorn Avatar asked Feb 06 '11 15:02

Acorn


People also ask

What is clean method in Django?

The clean_<fieldname>() method is called on a form subclass – where <fieldname> is replaced with the name of the form field attribute. This method does any cleaning that is specific to that particular attribute, unrelated to the type of field that it is. This method is not passed any parameters.

How do you remove this field is required Django?

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.

How can you validate Django model fields?

to_python() method of the models. Field subclass (obviously for that to work you must write custom fields). Possible use cases: when it is absolutely neccessary to ensure, that an empty string doesn't get written into the database (blank=False keyword argument doesn't work here, it is for form validation only)

Which method has a form instance which runs validation routines for all its fields?

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.


2 Answers

I think the process of form validation (and its correct order) is really well documented.

Would you mind sharing your code? There is a clean method on every formfield, responsible for running to_python, validate and run_validators (in this order). to_python accepts the raw value of the widget, coercing it into a python type, validate takes the coerced value and runs field-specific validation.

Answer updated with regards to the code given

clean_message is called after all the other validation has run like to_python, validate and, most importantly, run_validators. I think the last method will check the that the max_length constraint isn't violated. So you changing the data afterwards has no affect.

The solution is to raise a ValidationError here. Removing max_length will avoid any validation on the input's length.

class ContactForm(forms.Form):     message = forms.CharField(widget=forms.Textarea)      def clean_message(self):         message = self.cleaned_data['message']         message = message.replace('a', '') # remove all "a"s from message         if len(message) >= 5:             raise ValidationError('Too many characters ...')         return message 
like image 122
Reiner Gerecke Avatar answered Sep 23 '22 00:09

Reiner Gerecke


As an extra, when is_valid() return False, you can check why, printing self.errors inside the form.

if you watch the is_valid() code, this checks the form is_bound and the self.errors is empty

like image 34
Nicolas Rojo Avatar answered Sep 20 '22 00:09

Nicolas Rojo