Reputation: 1266
I have seen many answers here where the recommended course of action in overloading a given default method from Django is to simply copy the code from that original method, and include it with your modifications in your overloaded version of said method.
For example, an answer given:
class MyUpdateView(UpdateView):
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.user = self.request.user
self.object.save()
return HttpResponseRedirect(self.get_success_url())
# the default implementation of form_valid is...
# def form_valid(self, form):
# self.object = form.save()
# return HttpResponseRedirect(self.get_success_url())
So the two lines that the answerer says are the default form_valid
are not actually the default code, but they are the code that gets executed through inheritance. Regardless, their answer removed the execution of any Django code forward of form_valid
and replaces it with a direct HttpResponseRedirect()
call.
The way I would write this method is as follows:
class MyUpdateView(UpdateView):
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.user = self.request.user
return super(MyUpdateView, self).form_valid(form)
Django's own code follows this convention. Taken from views/generic/edit.py
line 111:
def form_valid(self, form):
self.object = form.save()
return super(ModelFormMixin, self).form_valid(form)
This is the true default version of form_valid
that the answerer of this other question is referring to.
So the nut of this question: Is there any reason I shouldn't be using super()
in this way in my projects, in the same way that Django's code does it internally? The advantage, to me, is that if Django were to ever update the way that these views work internally, chances are much better that my code — which simply extends and continues to execute Django's — will remain compatible. In addition, it keeps me from re-writing code that is already written by simply executing the existing code with modifications. Is this not one of super()
's intended uses?
Upvotes: 2
Views: 457
Reputation: 31951
Yes, there is a reason.
Let's replace your super
call with actual Django method.
class MyUpdateView(UpdateView):
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.user = self.request.user
self.object = form.save() # oops, we redefined self.object, user won't be saved
return HttpResponseRedirect(self.get_success_url())
So this won't work. Of course using super
is always DRY'er and better, but it's not always possible.
In your example from Django source it is another situation: the child does saving and the parent does redirection. No "overlaps" here.
Upvotes: 3