chem1st
chem1st

Reputation: 1634

ValidationError in FormView Django

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.

Upvotes: 0

Views: 3526

Answers (1)

Alasdair
Alasdair

Reputation: 309109

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

Upvotes: 2

Related Questions