我建议使用super()不正确吗?

时间:2012-04-24 07:12:25

标签: django overloading python-2.7 super

我在这里看到很多答案,其中从Django重载给定默认方法的推荐做法是简单地从原始方法复制代码,并将其包含在您所述方法的重载版本中。

例如,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())

因此,回答者所说的默认form_valid这两行实际上并不是默认代码,但它们是通过继承执行的代码。无论如何,他们的回答删除了form_valid前面的任何Django代码的执行,并将其替换为直接HttpResponseRedirect()调用。

我写这种方法的方法如下:

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自己的代码遵循这个约定。取自views/generic/edit.py第111行:

def form_valid(self, form):
    self.object = form.save()
    return super(ModelFormMixin, self).form_valid(form)

这是另一个问题的回答者所指的form_valid的真正默认版本。

所以这个问题的坚果:我是否有任何理由不在我的项目中以这种方式使用super(),就像Django的代码在内部执行它一样?对我来说,优势在于,如果Django要更新这些视图在内部工作的方式,那么我的代码 - 只是扩展并继续执行Django的 - 将保持兼容的可能性要大得多。此外,它使我不必重新编写已经编写的代码,只需通过修改执行现有代码即可。这不是super()的预期用途吗?

1 个答案:

答案 0 :(得分:3)

是的,有一个原因。

让我们用实际的Django方法替换你的super调用。

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())

所以这不起作用。当然使用super总是更干,更好,但并不总是可行。

在你的Django源代码示例中,另一种情况是:子节点正在保存而父节点正在重定向。这里没有“重叠”。