如何使用Django mixin?

时间:2014-06-15 09:03:31

标签: python django django-views

在我的应用程序中,我有一堆DetailViews和ListViews。我需要向每个页面添加一个带有“最后访问过的页面”信息的面板。我知道我可以创建两个我自己的类,分别从DetailView和ListView继承并覆盖get_context_data方法,但这会使代码发生变化。目前我只需在每个视图中添加一行代码即可解决问题

context['panel_info'] = get_panel_info()

但我也不喜欢这个解决方案。 我的想法是使用自定义get_context_data方法创建一个Mixin,但据我所知,如果我继承这样的话

class MyView(DetailView, MyMixin):
    def get_context_data(self, **kwargs):
        context = super(MyView, self).get_context_data(**kwargs)
        return context

根本不会调用Mixin的方法。 那么最聪明的解决方案是什么呢?

2 个答案:

答案 0 :(得分:2)

有不同的方法可以做到这一点,如果你需要可以重复使用所有视图的东西,那么上下文处理器可能是解决方案,但如果你只需要在某些特定的视图上,那么Mixin也可以做到这一点。 你是怎么做到的:

class MyMixin(object):

    def get_context_data(self, **kwargs):
        context = super(MyMixin, self).get_context_data(**kwargs)
        context['panel_info'] = get_panel_info()
        return context


class MyView(MyMixin, DetailView):
   ...

您不需要覆盖MyView中的get_context_data以使Mixin正常工作。

答案 1 :(得分:1)

BurhanKhalid 一样,使用模板上下文处理器是一个聪明的解决方案。上下文处理器允许您指定在每个上下文中自动设置的多个变量。

唯一的问题是您需要使用RequestContext代替Context。所以,

def my_view(request):
    return render(request, 'template.html', {'whatever': 'whatever'},
                  context_instance=RequestContext(request))

制作上下文处理器。它基本上是一个接受HttpRequest并返回一个字典的方法。

def last_visited_pages_context_processor(request):
    # Your custom code
    return {'foo': 'bar'}

现在,只需将上下文处理器添加到 settings.py 中的TEMPLATE_CONTEXT_PROCESSORS

TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'your_app.context_processors.last_visited_pages_context_processor',
)

很高兴去。有关详情,请访问http://www.djangobook.com/en/2.0/chapter09.html