Process flow in Class-based views - I just don't get it

Hi all,

TL;DR:
Don’t understand some basics of CBVs. Would like to let my CreateView make some server-side checks on formfields before it redirects to another URL. Don’t know how to do it and would like to understand how I could have solved that by consulting the documentation.

Praise to the django documentation team
I’m new to django. At first I would like to make the whole django documentation team a huge compliment. It’s at least one of the best documentations I have read in the last years. So if anyone from the team is reading: Thanks so much!

Background
Actually I’m struggleing a bit with Class Based Views. After reading the documentation [1] and and API reference [2] I (think I) got some basic understanding on what’s happening. The cool diagrams [3] from @bmtymrak also helped to get some understanding of the processes.

The actual issue
I’m using a CreateView to create a form which input data is stored in a model after submitting it. Before the data from the form is stored in my model, I would like to perform some more complex checks on a server-side. For now, let’s just assume that I would like to test if formfield_one (an int value) is bigger than formfield_two (also an int). If that is True, a redirect to the success URL shall take place. Otherwise an error message shall be raised.

What to do?
Having a look at the CreateView API reference [4] unluckily didn’t help me. Looking at the CreateView’s diagram [3] I noticed, that the FormView (the CreateView inherits) seems to be able to make some form.is_valid() checks, but I can’t find anything about that in the official documentation [5]. So this seems to be a dead-end.
Looking at the UML diagram of the CreateView from another source [6], it shows me that the ModelFormMixin has a form_valid() function. In the ModelFormMixin documentation [7], I can see that there is a description for the form_valid method [==> “Saves the form instance, sets the current object for the view, and redirects to get_success_url()”]. But that’s the point where I don’t know what to do. :frowning:

Is this the point where I should place some additional checks? If that’s the case: How? :confused:
And for me even more important: How could I have found the answer in the documentation by myself?

Thanks and regards,
Toni

[1] Class-based views | Django documentation | Django
[2] Built-in class-based views API | Django documentation | Django
[3] hxxps://www.brennantymrak.com/articles/django-class-based-views-diagrams
[4] hxxps://docs.djangoproject.com/en/3.2/ref/class-based-views/generic-editing/#createview
[5] hxxps://docs.djangoproject.com/en/3.2/ref/class-based-views/mixins-editing/#django.views.generic.edit.ProcessFormView
[6] hxxps://learnbatta.com/course/django/django-create-view/
[7] hxxps://docs.djangoproject.com/en/3.2/ref/class-based-views/mixins-editing/#django.views.generic.edit.ModelFormMixin

The best resources I’ve seen for helping to understand the flow of the CBVs is the Classy Class-Based View site and the CBV diagrams pages.

First, when I need to do something like what you’re describing, I’d be looking at modifying the form before trying to modify the view. “Checks on formfields” sounds more like it fits into the various form validation processes than the view process.

This is clearly a function that belongs in the form’s clean method.

But beyond that, I agree that finding the “right” place to plug things in is tough at first. I think that the diagrams are great, but the Classy Class-Based View site has been the best resource for me.
(And there are two other sites built on the same technique - Classy Django Forms and Classy Django REST Framework

Now, if you run into a situation where it is appropriate to plug into form_valid, you’d be overriding a method in a class. You define a form_valid function in your CBV, and do whatever you’d want to do there. If all your checks “pass”, and you want to save that form and redirect to the success url, call super. (See the relationship between the form_valid function in ModelFormMixin and FormMixin.)

2 Likes

Thanks a lot for the great reply, @KenWhitesell !

Two more resources…

django-vanilla-views is a radically simplified set of view classes that make it much more obvious where to override stuff.

Django Views — The Right Way is a guide on using only functional views.

I prefer to write functional views myself these days. I had so many “I don’t understand this” moments when writing CBV’s, or returning to them.

4 Likes