文章目錄
  1. 1. 权限控制
  2. 2. 复合类页面
  3. 3. fbvs和cbvs源代码转换

谈一下一些解决方案

权限控制

思路

fbv里页面控制访问很简单,在方法上挂上几个修饰器,本质上是重写方法。cbv里控制访问权限使用mixin,django.contrib.auth.mixins里提供了几个基于django user的权限访问方法。只要你的用户是使用django user,或者和django user有联系的就可以直接调用它,例如挂上@login_required的fbv只要在cbv中继承LoginRequiredMixin即可。

django.contrib.auth.mixins里除去一个抽象类,总共有3个mixin,用于判断request.user.is_authenticated是否为True的LoginRequiredMixin,用于自定义权限的 PermissionRequiredMixin,和自己设置一个考验方法test_func,返回False就拒绝request的UserPassesTestMixin。注意抽象类AccessMixin里的get_login_url会自动调用全局变量settings.LOGIN_URL,不想这么做的话设置它的属性login_url即可(如果登录入口不止一个的话)

复合类页面

思路

之前用的Django-oscar框架的沙盒里,注册和登录界面是一起的,当然这种界面并不少见,很多网站都是用这种写法。但是Django没有这种view,这个时候不能直接同时继承TemplateViewCreateView。因为我们知道,『在同一个上下文中,同名函数或属性将会覆盖』,这样,我们就无法预知这个得到的视图会做出怎样的行为。为了减少代码耦合,并做到简单继承,我们就需要去看这两个视图的关系:

CreateView->(SingleObjectTemplateResponseMixin, BaseCreateView)

TemplateView->(ContextMixin, TemplateResponseMixin, View)

因此我们通过(获取数据(Context),渲染方法(TemplateResponse),请求处理(View))的思路得到相应view

LoginRegisterView->(BaseCreateView)

类似的,比如更新和删除页面:

UpdateView->(SingleObjectTemplateResponseMixin, BaseUpdateView)

DeleteView->(SingleObjectTemplateResponseMixin, BaseDeleteView)

得到

UpdateDeleteView->(SingleObjectTemplateResponseMixin, BaseUpdateView, BaseDeleteView)

fbvs和cbvs源代码转换

举例(TemplateView)

拿公司的代码举例, 原主页是一个后台管理界面的主界面,页面功能看上去很复杂,但是从源代码上看只是渲染了几个传入的变量而已。 传入变量的方法为get_context_data,这个方法的根方法在ContextMixin中,加上一个渲染引擎和基本view,之后发现TemplateView刚好够满足需要(真的是刚好),就直接用这个View即可,当然自己写view也可以。然后LoginRequiredMixin对应@login_required方法,直接继承即可,cbv的权限控制有一个专门的Mixin类。

原代码(fbv)

1
2
3
4
5
6
7
8
9
10
@login_required
def index_view(request):
"""后台主页
"""
staff = request.user.myuser
announcement_list = []
menu = 0
# announcement_list = Announcement.objects.filter(del_status=0).order_by("-create_time") ##获取公告信息
# vacate_count,hr_vacate_count = load_message(staff)
return render_to_response('dashboard/index.html', locals(), context_instance=RequestContext(request))

cbv代码

1
2
3
4
5
6
7
8
9
class IndexView(LoginRequiredMixin, generic.TemplateView):
template_name = 'dashboard/index.html'
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
context['staff'] = self.request.user.myuser
context['announcement_list'] = []
context['menu'] = 0
return context
文章目錄
  1. 1. 权限控制
  2. 2. 复合类页面
  3. 3. fbvs和cbvs源代码转换