一,需求描述
需要将当前用户拥有的文章分类信息展示到页面顶部。
前提是从django class-based view 中获取当前用户。
二,问题描述
与使用function view直接获取request信息不同的是,我这里将获取文章分类信息这个通用数据的处理抽象为一个CommonViewMixin,然后供其他class-based view进行继承,代码如下:
class CommonViewMixin(object):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context = super(CommonViewMixin, self).get_context_data(**kwargs)
context.update({
'sidebars': SideBar.get_all(),
})
context.update(Category.get_navs())
context.update(Category.get_navs(owner=3))
return context
如上所示,只能直接写入固定的userid:owner=3 来指定用户。
三,解决方案
1,继承generic class-based view
如果要通过继承其他generic class-based view来实现CommonViewMixin的话也可以。
因为大多数generic class-based view直接或间接继承自 django.views.generic.base.View ,View 中的 setup(request, *args, **kwargs) 方法会将HttpRequest分配给视图的request属性,并将从URL模式捕获的所有位置和/或关键字参数分别分配给args和kwargs属性供dispatch等方法在后面的方法流程中使用。
但是这样一来抽象程度就不高了也就失去了作为一个提供分离特性的Mixin的意义。
同时由于各个generic class-based view都有自己的实现,也就不利于CommonViewMixin其子类的功能拓展。
2,使用*args与**kwargs
参考django.views.generic.base.View.setup方法,写CommonViewMixin.setup方法。
简单快速。
class CommonViewMixin(object):
def __init__(self, request, *args, **kwargs):
"""Initialize attributes shared by all view methods."""
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
def get_context_data(self, **kwargs):
context = super(CommonViewMixin, self).get_context_data(**kwargs)
context.update({
'sidebars': SideBar.get_all(),
})
if self.request.method == 'GET':
context.update(Category.get_navs(owner=self.request.user.id))
return context
然后其他自定义class-based view继承这个CommonViewMixin。