form_invalid

665 views
Skip to first unread message

Roberto Russi

unread,
Jan 29, 2017, 7:10:20 AM1/29/17
to Django users
I need get data from a form when submit is clicked even if data are invalid, inconplete or empty.
I try to override form_invalid in CreateView but it is never called and form_valid, obviously, only if data are valid.
Why form_invalid is never called?

I have this test project with django 1.10.5 and python 3.5

models.py

class Demo(models.Model):
        demo_descr = models.CharField("Description",
            max_length=50,
        )
        demo_code = models.CharField("Code",
            max_length=5,
        )

        def __str__(self):
                return self.demo_descr
   
        class Meta:
            verbose_name = "Test"
            verbose_name_plural = "Tests"
            ordering = ["demo_descr"]

views.py

class DemoForm(forms.ModelForm):
    class Meta:
        model = models.Demo
        fields = ('demo_descr','demo_code')
  

class DemoCreateView(CreateView):
    form_class = DemoForm
    success_url = 'demo'
    template_name = 'test_form.html'
    model = models.Demo

    def form_valid(self, form):
        print('valid')
        return CreateView.form_valid(self, form)

    def form_invalid(self, form):
        print('invalid')
        return CreateView.form_invalid(self, form)

urls.py

url(r'^demo$', views.DemoCreateView.as_view(),  name='demo'),


test_form.html

<form method="post" action="">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Save" />
</form>

Norberto Bensa

unread,
Jan 29, 2017, 12:30:50 PM1/29/17
to django...@googlegroups.com
https://ccbv.co.uk is your friend with class based views.

I'd override post(self, request, *args, **kwargs), in request.POST, you'll have your form's data (before it's validated). 

HTH,
Norberto

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/c4ab5b85-13cc-4569-aa0d-5ef4dd6911a4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Roberto Russi

unread,
Jan 29, 2017, 1:54:16 PM1/29/17
to Django users
I have tried it but post method is called only if form is valid and not if there are mandatory field not filled.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.

Norberto Bensa

unread,
Jan 29, 2017, 2:26:10 PM1/29/17
to django...@googlegroups.com
Are you telling me the following doesn't work for you?

class DemoCreateView(CreateView):
...
def post(self, request, *args, **kwargs):
print(request.POST)
return super().post(request, *args, **kwargs)
...


Now, at the console:


<QueryDict: {'csrfmiddlewaretoken':
['A3hHKM6Bs6NjJA996ALAsYPcYR7M3NWkzP4wcd6WUX1CEazC1dAK3aD1n8zl1aUU'],
'demo_desc
r': [''], 'demo_code': ['']}>

...

BTW, I had to add "blank=True, null=True" to your models, otherwise
the fields are marked as required and the browser does validate that.

HTH,
Norberto
> To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/1262e431-5210-4707-bea6-0e8d8813c33b%40googlegroups.com.

Roberto Russi

unread,
Jan 29, 2017, 4:04:31 PM1/29/17
to Django users
But fields are required! I need to have a control over form also if 'save' button is clicked and required fields are not filled.

Melvyn Sopacua

unread,
Jan 29, 2017, 8:35:54 PM1/29/17
to django...@googlegroups.com

On Sunday 29 January 2017 04:10:20 Roberto Russi wrote:

> I need get data from a form when submit is clicked even if data are

> invalid, inconplete or empty.

> I try to override form_invalid in CreateView but it is never called

> and form_valid, obviously, only if data are valid.

> Why form_invalid is never called?

 

Because the form is blocked by client-side validation: it never gets to the server. If you watch the development console closely, you will see that when you press save, there is no incoming request.

 

Add the following clean method to DemoForm, fill in "bla" for demo_code in the form and you will see form_invalid being called.

 

def clean(self):
if self.data['demo_code'] != 'valid':
raise ValidationError('{}: Invalid demo code'.format(
self.data['demo_code']
))

--

Melvyn Sopacua

Norberto Bensa

unread,
Jan 29, 2017, 10:10:18 PM1/29/17
to django...@googlegroups.com
Then you need to make your model fields not required and override your
form.clean() methods, then you'll have complete control over the
validation process.

I see Melvyn already aswered.
> https://groups.google.com/d/msgid/django-users/59d268d9-269e-4875-a405-bc9c7985e506%40googlegroups.com.

Norberto Bensa

unread,
Jan 29, 2017, 10:11:58 PM1/29/17
to django...@googlegroups.com
BTW, IIRC, you can also make your model fields required (for db
consistency) but then you need to use django.forms.Form instead of
django.forms.ModelForm.

Roberto Russi

unread,
Jan 30, 2017, 11:52:39 AM1/30/17
to Django users
Is just what i pictured. But when form_invalid is called?

Daniel Roseman

unread,
Jan 30, 2017, 4:58:52 PM1/30/17
to Django users
This is bad advice. You should almost never need to override the get or post methods on a class based view; there are always more specific methods to use.
--
DR.
Reply all
Reply to author
Forward
0 new messages