0

What is the correct way of raising the ValidationError in a FormView and passing it to the template with reloaded form? Currently I have this:

class ProfileUpdateView(FormView):
    template_name = 'profile_update.html'
    form_class = UserDetailForm
    success_url = '/profile/'

    def form_valid(self, form):
        userdetail = form.save(commit = False)
        try:
            already_exist_info = UserDetail.objects.get(document_type=userdetail.document_type,
                series=userdetail.series, number=userdetail.number)
            raise forms.ValidationError("Document already exists in DB")
        except UserDetail.DoesNotExist:
            [... some stuff here ...]
            userdetail.save()
        return super(ProfileUpdateView, self).form_valid(form)

It works and I get the error page, but I would prefer to show the error in the template with reloaded form. Moreover, is there a built-in way to get ValidationError in FormView? I mean, without importing forms from django.

Thanx.

EDIT

Well, I've decided to do all the trick in other manner - using clear() method. So now I have this:

views.py

class ProfileUpdateView(FormView):
    template_name = 'profile_update.html'
    form_class = UserDetailForm
    success_url = '/profile/'

    def form_valid(self, form):
        userdetail = form.save(commit = False)
        #[... some stuff ...]
        userdetail.save()
        return super(ProfileUpdateView, self).form_valid(form)

forms.py

class UserDetailForm(forms.ModelForm):
    class Meta:
        model = UserDetail
        exclude = ('user', )

    def clean(self):
            cleaned_data = super(UserDetailForm, self).clean()
            document_type = cleaned_data.get("document_type")
            series = cleaned_data.get("series")
            number = cleaned_data.get("number")
            try:
                already_exist_info = UserDetail.objects.get(document_type=document_type,
                    series=int(series), number=number)
                raise forms.ValidationError("Document already exists in DB")
            except:
                pass
            return cleaned_data

Everything seems to be fine according to docs, however this time the form just saves without any errors.

4
  • Did you try form.add_error('field', 'error message')? Commented Nov 8, 2015 at 12:15
  • Yeap, it doesn't work since I guess my error doesn't belong to a specific field... Commented Nov 8, 2015 at 12:22
  • Ok, try getting rid of form.save. Can't you just access the data with form.cleaned_data? Commented Nov 8, 2015 at 12:28
  • See my updates. Yes, I can. Now I do this in clean() method in forms Commented Nov 8, 2015 at 12:40

1 Answer 1

2

Raising ValidationError in the form's clean method is the correct approach.

Your problem is that you are catching all exceptions, including ValidationError. If you change your code to catch a more specific exception, then it should work.

try:
    already_exist_info = UserDetail.objects.get(
        document_type=document_type,
        series=int(series), 
        number=number,
    )
    raise forms.ValidationError("Document already exists in DB")
except UserDetail.DoesNotExist:
    pass
return cleaned_data
Sign up to request clarification or add additional context in comments.

3 Comments

Will that work with the UpdateView if I use the form as form_class?
@RamiAlloush yes you should be able to do something similar in an update view. You may have to exclude the current object from the queryset (e.g. .exclude(pk=self.instance.pk).
If you’re still stuck please ask another question, I can’t help in the comments.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.