Django / Python:了解super在函数中的使用方式

时间:2015-12-02 15:44:40

标签: 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

2 个答案:

答案 0 :(得分:3)

正如目前所写,该方法绝对没有任何东西,可以删除。

上下文数据方法直接委托给继承链中的下一个类。在这种情况下,它将意味着使用超类<webflow:flow-registery id="flowRegistry" flow-builder-services="someFlowBuilderService"> <webflow:flow-location-pattern value="/**/*-flow.xml"/> <webflow:flow-builder class="com.my.package.MyCustomFlowModelFlowBuilder"/> </webflow:flow-registery>

但是,如果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的原因很复杂,并且与方法解析顺序(MRO)相关。 Raymond Hettinger对here进行了详细解释。

注意:在python 3中,super的实现被清理了一点,而你不再需要DetailView.get_context_data,你可以幸运地使用super(ArticleDetailView, self)

答案 1 :(得分:1)

super方法将访问当前类并调用特定方法,在这种情况下:

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

执行特定方法:

.get_context_data(**kwargs)

.get_context_data()类中的View方法,返回传递给模板的context.html文件)。在这种情况下,您使用的是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的上下文值。