简体   繁体   中英

django overwrite form clean method

When overwriting a form clean method how do you know if its failed validation on any of the fields? eg in the form below if I overwrite the clean method how do I know if the form has failed validation on any of the fields?

class PersonForm(forms.Form):
    title = Forms.CharField(max_length=100)
    first_name = Forms.CharField(max_length=100)
    surname = Forms.CharField(max_length=100)
    password = Forms.CharField(max_length=100)

def clean(self, value):
    cleaned_data = self.cleaned_data

    IF THE FORM HAS FAILED VALIDATION:
        self.data['password'] = 'abc'
        raise forms.ValidationError("You have failed validation!")
    ELSE:
        return cleaned_data 

Thanks

You can check if any errors have been added to the error dict:

def clean(self, value):
    cleaned_data = self.cleaned_data

    if self._errors:
        self.data['password'] = 'abc'
        raise forms.ValidationError("You have failed validation!")
    else:
        return cleaned_data 

BONUS! You can check for errors on specific fields:

def clean(self, value):
    cleaned_data = self.cleaned_data

    if self._errors and 'title' in self._errors:
        raise forms.ValidationError("You call that a title?!")
    else:
        return cleaned_data 

If your data does not validate, your Form instance will not have a cleaned_data attribute

Django Doc on Accessing "clean" data

Use self.is_valid() .

Although its old post, if you want to apply validations on more than 1 field of same form/modelform use clean() . This method returns cleaned_data dictionary.

To show the errors to users you can use add_error(<fieldname>, "your message") method. This will show the errors along with the field name rather on top of the form. The example is shown below:

add_error() automatically removes the field from cleaned_data dictionary, you dont have to delete it manually. Also you dont have to import anything to use this.

documentation is here

def clean(self):

  if self.cleaned_data['password1'] != self.cleaned_data['password2']:
    msg = 'passwords do not match'
    self.add_error('password2', msg)

  return self.cleaned_data

If you just want validation on single field of form/modelform use clean_<fieldname>() . This method will take the values from cleaned_data dictionary and then you can check for logical errors. Always return the value once you are done checking logic.

def clean_password(self):

  password = self.cleaned_data['password']

  if len(password)<6:
    msg = 'password is too short'
    self.add_error('password', msg)

  return password

Here is a simple example of overriding clean() in django.forms.Form and also using django-braces for AnonymousRequiredMixin to require that only anonymous users visit the Loing Page:

class LoginView(AnonymousRequiredMixin, FormView):
    """
    Main Login. And Social Logins
    """
    template_name = 'core/login.html'
    form_class = LoginForm
    success_url = reverse_lazy('blog:index')

    def get_success_url(self):
        try:
            next = self.request.GET['next']
        except KeyError:
            next = self.success_url
        return next

    def form_valid(self, form):
        cd = form.cleaned_data
        user = auth.authenticate(username=cd['login_username'], 
            password=cd['login_password'])
        if user:
            auth.login(self.request, user)
            messages.info(self.request, 'You are logged in.')
        return super(LoginView, self).form_valid(form)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM