Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I raise a ValidationError (or do something similar) in views.py of my Django?

I'm using Django forms. I'm validating in the model layer:

def clean_title(self):
    title = self.cleaned_data['title']
    if len(title)  < 5:
        raise forms.ValidationError("Headline must be more than 5 characters.")
    return title

However, there are some things that I need to validate in the views.py . For example...was the last time the user posted something more than a minute ago?

That kind of stuff requires request.user, which the models layer cannot get. So, I must validate in the views.py. How do I do something in the views.py to do the exact thing as this?

raise forms.ValidationError("Headline must be more than 5 characters.")
like image 716
TIMEX Avatar asked Dec 19 '10 09:12

TIMEX


People also ask

How do I increase my ValidationError?

For any field, if the Field. clean() method raises a ValidationError , any field-specific cleaning method is not called. However, the cleaning methods for all remaining fields are still executed.

How do I display validation error in Django?

To display the form errors, you use form. is_valid() to make sure that it passes validation. Django says the following for custom validations: Note that any errors raised by your Form.

What is clean method in Django?

The clean_<fieldname>() method: Use this method when you want to do a cleaning on a form field attribute unrelated to the type of the field. For example, you want to make sure that a particular field is unique.


3 Answers

I think gruszczy's answer is a good one, but if you're after generic validation involving variables that you think are only available in the view, here's an alternative: pass in the vars as arguments to the form and deal with them in the form's main clean() method.

The difference/advantage here is that your view stays simpler and all things related to the form content being acceptable happen in the form.

eg:

# IN YOUR VIEW 
# pass request.user as a keyword argument to the form
myform = MyForm(user=request.user)


# IN YOUR forms.py
# at the top:

from myapp.foo.bar import ok_to_post # some abstracted utility you write to rate-limit posting 

# and in your particular Form definition

class MyForm(forms.Form)

   ... your fields here ...

   def __init__(self, *args, **kwargs):
      self.user = kwargs.pop('user')  # cache the user object you pass in
      super(MyForm, self).__init__(*args, **kwargs)  # and carry on to init the form


   def clean(self):
      # test the rate limit by passing in the cached user object

      if not ok_to_post(self.user):  # use your throttling utility here
          raise forms.ValidationError("You cannot post more than once every x minutes")

      return self.cleaned_data  # never forget this! ;o)

Note that raising a generic ValidationError in the clean() method will put the error into myform.non_field_errors so you'll have to make sure that your template contains {{form.non_field_errors}} if you're manually displaying your form

like image 139
Steve Jalim Avatar answered Oct 27 '22 16:10

Steve Jalim


You don't use ValidationError in views, as those exceptions as for forms. Rather, you should redirect the user to some other url, that will explain to him, that he cannot post again that soon. This is the proper way to handle this stuff. ValidationError should be raised inside a Form instance, when input data doesn't validate. This is not the case.

like image 29
gruszczy Avatar answered Oct 27 '22 16:10

gruszczy


You can use messages in views:

from django.contrib import messages

messages.error(request, "Error!")

Documentation: https://docs.djangoproject.com/es/1.9/ref/contrib/messages/

like image 4
ThomasAFink Avatar answered Oct 27 '22 15:10

ThomasAFink