Generic editing views - self.object vs self.get_object( )

Hi, while creating some DeleteViews, I observed that it is possible to use self.object and self.get_object() for the same thing, interchangeably.

These are the views (get_success_url methods were where the two options were used):

View using self.get_object()

class ChlorinatorDeleteView(PermissionRequiredMixin, DeleteView):
    model = Chlorinator
    permission_required = 'components.delete_chlorinator'

    def form_valid(self, form):
        try:
            success_url = self.get_success_url()
            self.object.delete()
            return HttpResponseRedirect(success_url)
        except Exception as e:
            return HttpResponseRedirect(
                reverse_lazy('schemes:delete-chlorinator', kwargs={'pk2': self.object.scheme.pk, 'pk': self.object.pk})
            )

    def get_success_url(self) -> str:
        return reverse_lazy('schemes:chlorinator-list', args=[self.get_object().scheme.id])

View using self.object

class TankDeleteView(PermissionRequiredMixin, DeleteView):
    model = Tank
    permission_required = 'comonents.delete_tank'

    def form_valid(self, form):
        try:
            success_url = self.get_success_url()
            self.object.delete()
            return HttpResponseRedirect(success_url)
        except Exception as e:
            return HttpResponseRedirect(
                reverse_lazy('schemes:delete-tank', kwargs={'pk2': self.object.scheme.id, 'pk': self.object.id})
            )

    def get_success_url(self) -> str:
        return reverse_lazy('schemes:tank-list', args=[self.object.scheme.id])

I’m interested to know if they are the same thing, or which is the ‘conventionally’ better option to use… Any light shed on the matter is much appreciated.

The self.object attribute is set by a call to self.get_object in the get and post methods. This means you can use self.object if your code in the view gets called downstream from the method calls to get or post, otherwise you need to use get_object.

For a better understanding of the CBVs, I recommend the Classy Class Based Views site and the CBV diagrams page.

1 Like

Ken Whitesell via Django Forum writes:

For a better understanding of the CBVs, I recommend the Classy Class
Based Views site and the CBV diagrams page.

Oh, thanks for mentioning them, I didn’t know these existed! :pray:

But I’m not entirely sure they actually help a lot in getting a better
understanding of CBVs. I mean look at the diagram for CreateView for
example.

Maybe this is more of an illustration why CBVs are hard to use beyond
some standard usecases? (And why I consider Mixins to bad in general)

But I bet most people are better in navigating these maps than I
am. What works for me most of the time is to use my editor to walk up
and down the hierarchy and look at the source code.

On the other hand I think this is still a good read on why FBVs might be
a better alternative to CBVs for some cases:

Django Views — The Right Way

I’m not saying CBVs are bad in general, but I think they come at a not
obvious cost later on.

PS: Sorry, my initial post got mangled somehow.

(attachments)

1 Like

Thank feels like an exceptionally satisfying answer after all the hours I’ve spent trying to make sense of it. As always, thank your very much, Ken!

Yes, there are situations where an FBV is clearly better. No argument there. Many of my projects have a mix of both CBVs and FBVs.

One point that I think needs to be (re)emphasized here is that the Django-provided generic CBVs are not the only possible set of CBVs that can be created. (See http://django-vanilla-views.org/ as another example. Or see Neapolitan for a completely different approach.)

The Django generic CBVs provide a solution for providing a very generic set of views for a particular category of use-cases, but are not the only solution.

I don’t think one should look at the Django-provided CBVs and automatically come to the conclusion that CBVs themselves are necessarily complex and difficult to understand. (Unfortunately, I think it has become common usage that the acronym CBV is used to refer to the Django-provided CBVs without recognition of the larger world of CBVs that exist. Somehow I don’t see DPGCBV catching on…)

Ken Whitesell writes:

Unfortunately, I think it has become common usage that the acronym CBV
is used to refer to the Django-provided CBVs without recognition of
the larger world of CBVs that exist.

Yes, excellent point. I was obviously referring to DPGCBVs by just
mentioning CBVs. I knew there were some other implementations of CBVs,
but have to admit that I never really checked them out. So CBVs were
basically the ones that come with Django. So if there is actually a
larger world of CBVs out there, I guess I should have a closer look at
some of them. Thanks!