• Django学习笔记一十九——补充内容:视图中的CBV和FBV (2020-05-15 15:05)


    前面的总结忘记了很重要的一项:视图Views,还有视图的两种模式:CBV和FBV

    从最简单的视图说起

     视图就是一个视图函数(类),从Web接受请求然后给Web返回一个响应。响应可以是一个网页的HTML内容(HttpResponse),也可以是个重定向(redirect),也可以是个404错误,或者一个XML文档、一张图片。

    视图是必须有返回值的,不管他是什么逻辑,最后都要返回一个response,只需要把他放在当前的目录下面,就没有什么别的特别需求了。但是有个约定俗成的习惯,就是把代码放在项目或应用程序中(app)的views.py文件中。

    我们看一下下面的代码

    from django.shortcuts import HttpResponse
    
    
    def test(request):
        print('in test')
        return HttpResponse('test123')

    上面就是一个最简单的视图,有请求(输入的request),有返回(HttpResponse)

    首先,我们从Django中导入了HttpResponse模块

    接着,我们随便做了一个功能。功能的逻辑直接忽略。然后返回一个HttpResponse对象。

    CBV和FBV

     我们前面写的所有的视图都是基于函数的,就叫做FBV(function base views),除此以外,还可以把视图携程基于类的,就是CBV(Class base views),我们就用一个最简单的案例来比较一下CBV和FBV的区别

    一个简单的视图

    就是一个注册的页面,先看看FBV的效果

    def login(request):
        if request.method == 'POST':
            name = request.POST.get('user')
            pwd = request.POST.get('pwd')
    
            if name == 'aaa' and pwd =='bbb':
                rep = HttpResponse('登录成功')
                return rep
            
            else:
                return redirect('/session_test/login')
        else:
            return render(request,'login.html')

    然后再看看CBV是怎么写的

    from django.views import View
    
    class Login(View):
    
        #method为get
        def get(self,request):
            return render(request,'login.html')
    
        #method为post
        def post(self,request):
            name = request.POST.get('user')
            pwd = request.POST.get('pwd')
    
            if name == 'aaa' and pwd =='bbb':
                rep = HttpResponse('登录成功')
                return rep
            
            else:
                return redirect('/session_test/login')

    但是两个方法在路由中注册的时候是有区别的

    url('^session_test/login',v2.login),          #FBV的注册方法
    url('^session_test/login',v2.Login.as_view()),   #CBV的注册方法

    FBV和CBV是没有哪个好哪个不好的,适合的就是最好的。

    CBV中的装饰器

     在FBV中,由于我们用到的装饰器都是函数装饰器,用来装饰函数的,但是在CBV中就会出问题了,看一下下面的案例,还是前面讲过的登录校验

    def check_login(func):
        @wraps(func)
        def inner(request,*args,**kwargs):
            ret = request.session.get('is_log')
            if ret == 1:
                return func(request,*args,**kwargs)
    
            else:
                return redirect('/session_test/login/')
    
        return inner
    
    
    
    class Home(View):
        @check_login
        def get(self,request):
            return render(request,'home.html')

    我们对一个页面在请求的时候先进行登录校验,如果没有登录就重新登录,否则直接进入主页面。但是这样运行完了会出现bug

     原因就是我们在对装饰器传参数的时候,第一个参数是request,但是在类里的函数中,第一个参数就是self,当然会报错,所以这个装饰器就是函数装饰器,我们需要在使用的时候把他指定成类装饰器:

    from django.utils.decorators import method_decorator
    class Home(View):
        @method_decorator(check_login)
        def get(self,request):
            return render(request,'home.html')

    这样就可以了!

    加给类的装饰器

    刚才的装饰器是直接加给类里面的方法的,我们还可以直接加到类上

    @method_decorator(check_login,name='get')
    class Home(View):
        
        def get(self,request):
            return render(request,'home.html')

    但是要注意的是加载类的前面的时候必须用关键字name指定装饰器是给哪个方法用的。

    补充一点:跨站伪装请求的处理

     我们前面的所有案例中,对于跨站伪装请求的处理有两种方法:

    1.在settings.py文件中直接注释掉csrf的中间件

    2.在form中通过{token_csrf}获取到csrf的标签

    其实还可以通过装饰器来处理

    排除校验

    from django.views.decorators.csrf import csrf_exempt,csrf_protect
    @csrf_exempt
    def login(requst):
        pass

    上面的装饰器可以使被装饰的函数排除校验(即便是中间件指定了校验)

    指定校验

    from django.views.decorators.csrf import csrf_exempt,csrf_protect
    @csrf_protect
    def login(requst):
        pass

    上面的方法是指定函数必须通过校验。

  • 相关阅读:
    8.31前端 jQuery
    8.30前端jQuery和数据结构知识
    8.29 jQuery
    8.28 jQuery
    8.27 jQuery
    8.26 js
    chrome开发工具指南(十二)
    chrome开发工具指南(十一)
    chrome开发工具指南(十)
    chrome开发工具指南(九)
  • 原文地址:https://www.cnblogs.com/yinsedeyinse/p/12907842.html
Copyright © 2020-2023  润新知