Django REST 框架的 FBV 与 CBV 选择

2021-01-12 09:58:52 浏览数 (1)

文章目录

    • 一、什么是 FBV与CBV
        • FBV: function base view
        • CBV: class base view
    • 二、CBV 实现原理:反射
    • 三、CBV 面向对象
        • 1.封装
        • 2.继承
    • 四、Django 中间件方法与流程

一、什么是 FBV与CBV

FBV: function base view

views.py

代码语言:javascript复制
from django.shortcuts import render,HttpResponse
import json

def users(request):    
    user_list = {
        "name": "tom",
        "age":27
    }
    return HttpResponse(json.dumps(user_list))

urls.py

代码语言:javascript复制
from django.contrib import admin
from django.urls import path
from tutorial01 import views

urlpatterns = [
    path('users',views.users),
    path('admin/', admin.site.urls),
]
CBV: class base view

推荐使用CBV

views.py

代码语言:javascript复制
from django.shortcuts import render,HttpResponse
from django.views import View


class UsersView(View):
    # 如何知道数据传输方法?
    # 通过反射实现
    # getattr(obj, request.method)
    
    def get(self, request, *args, **kwargs):
        return HttpResponse("GET")

    def post(self, request, *args, **kwargs):
        return HttpResponse("POST")

urls.py

代码语言:javascript复制
from django.contrib import admin
from django.urls import path
from tutorial01 import views

urlpatterns = [
    path('users',views.UsersView.as_view()),
    path('admin/', admin.site.urls),
]

二、CBV 实现原理:反射

反射机制就是在运行时,动态的确定对象的类型,并可以通过字符串调用对象属性、方法、导入模块,是一种基于字符串的事件驱动。 在python中支持反射机制的函数有getattr()、setattr()、delattr()、exec()、eval()、__import__

CBV 基于反射来根据请求方式不同,执行不同方法

ChildView 子类继承 View 父类后,

浏览器通过url传给路由,由as_view 进入ChildView,ChildView通过View的 dispatch 方法来根据不同请求方法执行不同的方法

代码语言:javascript复制
class View:
    # ...
    def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesn't exist,
        # defer to the error handler. Also defer to the error handler if the
        # request method isn't on the approved list.
        if request.method.lower() in self.http_method_names:
            # 通过 getattr 实现反射机制
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)

三、CBV 面向对象

1.封装
2.继承

避免重复编写共用的功能

代码语言:javascript复制
class MyBaseView(object):
    def dispatch(self, request, *args, **kwargs):
        print('before')
        # 执行父类的 dispatch 方法
        # super 除了可以让子类继承父类的方法,同时还可以执行子类的其他父类的 方法
        ret = super(MyBaseView, self).dispatch(request, *args, **kwargs)
        print('after')
        return ret


# 继承时,前面的类优先级高
class UsersView(MyBaseView, View):
    def get(self, request, *args, **kwargs):
        print('get')
        return HttpResponse("GET")

    def post(self, request, *args, **kwargs):
        return HttpResponse("POST")

输出

代码语言:javascript复制
Quit the server with CTRL-BREAK.
before
get
after

四、Django 中间件方法与流程

中间件负责把各个模块将客户端请求经过路由匹配和视图处理返回给客户端

包括五个方法

  • process_request
  • process_response
  • process_view
  • process_exception
  • process_render_template

执行流程

0 人点赞