Django/Python:理解函数中 super 的用法

4

我刚开始理解super是什么以及它在Django的视图类中是如何实现的。我正在尝试理解以下代码中super是如何工作的。有人能够逐个部分地为我解释一下吗?

from django.views.generic.detail import DetailView
from apps.app_name.models import Article

class ArticleDetailView(DetailView):
    model = Article
    template_name = 'article/show.html'

    def get_context_data(self, **kwargs):
        context = super(ArticleDetailView, self).get_context_data(**kwargs)
        return context

它的哪个部分不够清晰?它调用了该方法的基类实现。 - Sayse
2个回答

6
< p > super 方法将访问当前类并调用特定方法,例如:

super(ArticleDetailView, self)  # Access to the current class

并执行特定的方法:

.get_context_data(**kwargs)

在一个View类中,.get_context_data()方法会返回传递给模板(.html文件)的context。在这种情况下,您正在使用DetailView,因此有一些预定义的上下文,例如:objectarticle
如果您只是覆盖.get_context_data()而没有调用.super(),如下所示:
def get_context_data(self, **kwargs):
    my_context = {...}
    return my_context

DetailView 上下文中,您将失去预定义的变量。但是,如果您想要向当前 DetailView 的上下文添加一些新变量(值),您需要原始上下文,这就是 super(ArticleDetailView, self).get_context_data(**kwargs) 提供的内容。因此,您可以按照以下方式使用它:

def get_context_data(self, **kwargs):
    context = super(ArticleDetailView, self).get_context_data(**kwargs)
    context.update({'my_key': 'my_value'})
    return context

现在您可以在模板中使用自己的值,而不会丢失默认的DetailView上下文值。

那么在这种情况下,super 对我唯一的作用就是获取 modeltemplate_name,以便我可以在 get_context_data 中使用它们? - Erik Åsland
1
get_context_data 方法返回模板中可以使用的值。在这种情况下,您正在重写 get_context_data 方法,因此如果您不想丢失默认的 DetailView 上下文数据,则需要使用 super 调用原始的 get_context_data 方法,然后将新值添加到上下文并将其返回给模板。是的,您可以使用它来添加新值并在模板中使用它们。 - Gocht
嗨,谢谢你的回复。正如你所提到的,super方法可以访问当前类。那么self和super之间有什么区别呢?接下来,在调用super(ArticleDetailView, self).get_context_data(**kwargs)时似乎会产生无限循环。请你能详细解释一下吗? - Mostafa Ghadimi

5
目前的代码中,该方法根本不起作用,可以将其删除。
上下文数据方法直接委托给继承链中的下一个类。在这种情况下,意味着会使用超类DetailView.get_context_data。但是,如果ArticleDetailView上不存在此方法,这样做也会发生。因此,明确地传递给超类是没有意义的。所以,这段代码很奇怪——这回答了你的问题吗?
如果你实际上想在子类中执行不同的操作,那么实现此方法就有意义。例如:
def get_context_data(self, **kwargs):
    context = super(ArticleDetailView, self).get_context_data(**kwargs)
    context['new_key'] = 'some injected context from ArticleDetailView'
    return context

然后我们使用来自DetailView的上下文数据,并在ArticleDetailView中添加其他上下文。使用super(ArticleDetailView, self).get_context_data而不是直接使用DetailView.get_context_data的原因比较复杂,与方法解析顺序(MRO)相关。Raymond Hettinger在这里详细解释了它。请注意:在Python 3中,super的实现变得更加清晰,您不再需要super(ArticleDetailView, self),只需使用super()即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接