2

我在这里看到了很多答案,其中推荐的从 Django 重载给定默认方法的操作过程是简单地从该原始方法复制代码,并将其与您的修改一起包含在所述方法的重载版本中。

例如,给出的答案

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实际上并不是默认代码,而是通过继承执行的代码。无论如何,他们的回答删除了任何 Django 代码的执行,form_valid并用直接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()'s 的预期用途之一吗?

4

1 回答 1

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

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.

于 2012-04-24T07:21:09.467 回答