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')

 

 

 

posted @ 2019-09-13 11:00  一只小羊  阅读(407)  评论(0编辑  收藏  举报