django CBV 及其装饰器
#urls.py from django.contrib import admin from django.urls import path, re_path from app01 import views urlpatterns = [ path('admin/', admin.site.urls), re_path(r'^student/', views.StudentView.as_view()), ]
#views.py from django.shortcuts import render, HttpResponse from django.views import View from app01 import models class StudentView(View): def get(self, request): models.UserInfo.objects.create(name='yyy', password='123') return HttpResponse('hello word')
装饰器:
1、* 加在dispatch方法上*
(1)CSRF Token相关装饰器在CBV只能加到dispatch方法上
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
class UploadFileView(View):
"""上传文件"""
@method_decorator(csrf_exempt) # CSRF Token相关装饰器在CBV只能加到dispatch方法上
def dispatch(self, request, *args, **kwargs):
return super(UploadFileView, self).dispatch(request, *args, **kwargs)
def get(self, request, *args, **kwargs):
return render(request, "thickness/upload_file.html")
def post(self, request, *args, **kwargs):
result = {'status': False, 'code': 1, 'percent': 0, 'count': 0, 'done_status': False}
.............
return HttpResponse(json.dumps(result))
(2)login装饰器
使用类定义的view,是不能够直接使用 login_required进行装饰的
需要重新定义一个 LoginRequired类,让视图类去继承:
1 from django.contrib.auth.decorators import login_required
2 from django.utils.decorators import method_decorator
3
4
5 class LoginRequiredMixin(object):
#dispath 这么写所有的请求方法都要做登录校验
6 @method_decorator(login_required(login_url="/login/"))
7 def dispatch(self, request, *args, **kwargs):
8 return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
9
10
11 #views
12 class IndexView(LoginRequiredMixin, View):
13 """首页"""
14 def get(self, request, *args, **kwargs):
15
16 return render(request, "index.html")
2、*CBV结合装饰器*
(1)直接加在视图类上,但method_decorator必须传 name 关键字参数
from django.shortcuts import redirect, render from django.contrib.auth import models def wrapper(func): def inner(request, *args, **kwargs): exist = models.User.objects.count() if exist != 0: ret = func(request, *args, **kwargs) print('已走装饰器') return ret else: return redirect("/thick-admin/") return inner @method_decorator(wrapper, name="get") class LoginView(View): def get(self, request, *args, **kwargs): return render(request, 'login.html') def post(self, request, *args, **kwargs): error_msg = '' username = request.POST.get('username') password = request.POST.get('password') rmb = request.POST.get('rmb') user = authenticate(username=username, password=password) if user: print("passed authentication") login(request, user) # 把user封装到request.session中 if rmb: request.session.set_expiry(60 * 60 * 24 * 30) print('rmb') return redirect(request.GET.get('next', '/thickness/index')) # 登录后跳转至next指定的页面,否则到首页 else: error_msg = "用户名或密码错误!" return render(request, 'login.html', locals())
(2)加在CBV视图的get或post方法上
1 class LoginView(View): 2 @method_decorator(wrapper) 3 def get(self, request, *args, **kwargs): 4 return render(request, 'login.html')