如何使用Django混合类?

0 投票
2 回答
1622 浏览
提问于 2025-04-18 09:50

在我的应用里,有很多详细视图和列表视图。我需要在每个页面上添加一个面板,显示“最近访问的页面”信息。我知道我可以创建两个自己的类,一个继承自详细视图,另一个继承自列表视图,然后重写get_context_data这个方法,但这样会导致代码重复。目前我解决这个问题的方法是,在每个视图里简单地添加一行代码

context['panel_info'] = get_panel_info()

但我也不喜欢这个解决方案。我的想法是创建一个混入类(Mixin),里面有自定义的get_context_data方法,但据我所知,如果我这样继承

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

混入类的方法根本不会被调用。那么,最聪明的解决方案是什么呢?

2 个回答

1

正如BurhanKhalid提到的,使用模板上下文处理器是个聪明的解决办法。上下文处理器可以让你指定一些变量,这些变量会在每次上下文中自动设置。

唯一需要注意的是,你需要用RequestContext来替代Context。所以,

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

你需要创建一个上下文处理器。它基本上是一个方法,这个方法接收一个Http请求,然后返回一个字典。

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

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,这样混入就可以正常工作了。

撰写回答