Django中的FBV和CBV

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)