Django/Python:了解如何在函数中使用 super

Eri*_*and 4 python django

我刚刚开始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
Run Code Online (Sandbox Code Playgroud)

Goc*_*cht 6

super方法将访问当前类并调用特定方法,在本例中:

super(ArticleDetailView, self)  # Access to the current class
Run Code Online (Sandbox Code Playgroud)

并执行具体方法:

.get_context_data(**kwargs)
Run Code Online (Sandbox Code Playgroud)

.get_context_data()类中的方法,View返回context传递给模板(.html文件)的内容。在本例中,您使用的是DetailView,因此您有一些预定义的上下文,例如:objectarticle

如果您只是覆盖.get_context_data()而不调用.super(),如下所示:

def get_context_data(self, **kwargs):
    my_context = {...}
    return my_context
Run Code Online (Sandbox Code Playgroud)

您将丢失上下文中的预定义变量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
Run Code Online (Sandbox Code Playgroud)

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


wim*_*wim 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
Run Code Online (Sandbox Code Playgroud)

然后我们使用来自 的上下文数据DetailView,并在 中添加额外的上下文ArticleDetailView

使用super(ArticleDetailView, self).get_context_data而不是简单地DetailView.get_context_data直接使用的原因很复杂,并且与方法解析顺序(MRO)有关。Raymond Hettinger 在这里进行了一些详细的解释。

注意:在 python 3 中 super 的实现被清理了一点,你不再需要super(ArticleDetailView, self)你可以使用,super()谢天谢地。