美文网首页
Django中的FBV和CBV

Django中的FBV和CBV

作者: 戴维得 | 来源:发表于2017-10-03 23:07 被阅读0次

    FBV

    fbv就是在url中一个路径对应一个函数

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^index/', views.index)
    ]
    

    在视图函数中

    def index(request):
        return render(request, 'index.html')
    

    CBV

    cbv就是在url中一个路径对应一个类

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^index/', views.IndexView.as_view())     # 执行类后面的as_view()方法,是父类里面的方法
    ]
    

    在视图函数中

    from django.views import View
    
    
    class IndexView(View):
      
        # 以get形式访问会执行get函数,一般情况下获取数据
        def get(self, *args, **kwargs):  
            return HttpResponse('666')
          
        # 以post形式访问的话会执行post函数,一般情况下发送数据
        def post(self, *args, **kwargs):  
            return HttpResponse('999')
    

    注意:

    • cbv定义类的时候必须要继承view
    • 在写url的时候必须要加as_view
    • 类里面使用form表单提交的话只有get和post方法
    • 类里面使用ajax发送数据的话支持定义以下很多方法
      restful规范:
      'get'获取数据, 'post'创建新数据, 'put'更新, 'patch'局部更新, 'delete'删除, 'head', 'options', 'trace'

    CBV重新定义dispatch函数

    所有的方法本质上都是通过dispatch这个函数反射执行,如果想要在执行get或post方法前执行其他步骤,可以重写dispatch

    class IndexView(View):
    
        # 重写父类的dispatch方法,如果不重写,他会执行父类的dispatch方法,
        def dispatch(self, request, *args, **kwargs):
            print('before')
            res = super(IndexView, self).dispatch(request, *args, **kwargs)
            print('after')
            return res
          
        # 以get形式访问会执行get函数
        def get(self, *args, **kwargs):  
            return HttpResponse('666')
          
        # 以post形式访问的话会执行post函数
        def post(self, *args, **kwargs):  
            return HttpResponse('999')
    

    下面我们根据上面的写法添加用户登录验证

    from django.shortcuts import render, HttpResponse, redirect
    
    from django.views import View
    
    class LoginView(View):
        def get(self, request):
            return render(request, 'login.html')
    
        def post(self, request):
            user = request.POST.get('user')
            pwd = request.POST.get('pwd')
            if user == 'rdw' and pwd == '666':
                request.session['user_info'] = 'rdw'
                return redirect('/index/')
            else:
                return render(request, 'login.html')
    
    class IndexView(View):
    
        # 重写父类的dispatch方法,如果不重写,他会执行父类的dispatch方法,
        def dispatch(self, request, *args, **kwargs):
            if not request.session.get('user_info'):
                return redirect('/login/')
            res = super(IndexView, self).dispatch(request, *args, **kwargs)
            return res
        # 以get形式访问会执行get函数
        def get(self, request, *args, **kwargs):  
            return render(request, 'index.html')
        # 以post形式访问的话会执行post函数
        def post(self, *args, **kwargs):  
            return HttpResponse('999')
    

    给视图类添加装饰器

    如果有多个程序需要用户登录验证的话会造成代码冗余,可以使用继承很好的解决这个问题,但是还有更好的方法,那就是基于装饰器实现登录验证

    定义装饰器

    def login_test(func):
        def inner(request, *args, **kwargs):
            if not request.session.get('user_info'):
                return redirect('/login/')
            return func(*args, **kwargs)
        return inner
    
    1. 直接添加在dispatch里面,这样每个函数都会执行

      from django.utils.decorators import method_decorator

      @method_decorator(login_test)
      def dispatch(self, request, *args, **kwargs):
      res = super(IndexView, self).dispatch(request, *args, **kwargs)
      return res

    2. 添加在每一个函数中

      from django.utils.decorators import method_decorator

      @method_decorator(login_test)
      def get(self, request, *args, **kwargs):
      return render(request, 'index.html')

    3. 直接添加在类上,后面的name表示只给get添加装饰器

      from django.utils.decorators import method_decorator

      @method_decorator(login_test, name='get')
      class IndexView(View):

    注意:

    • 添加装饰器前必须导入from django.utils.decorators import method_decorator
    • 添加装饰器的格式必须为@method_decorator(),括号里面为装饰器的函数名
    • 给类添加是必须声明name
    • 注意csrf-token装饰器的特殊性,它只能加在dispatch上面

    相关文章

      网友评论

          本文标题:Django中的FBV和CBV

          本文链接:https://www.haomeiwen.com/subject/nnqqyxtx.html