一、什么是 FBV与CBV

FBV: function base view

views.py

from django.shortcuts import render,HttpResponse
import json

def users(request):
user_list = {
"name": "tom",
"age":27
}
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

from django.contrib import admin
from django.urls import path
from tutorial01 import views

urlpatterns = [
path('users',views.users),
path(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

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(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

from django.contrib import admin
from django.urls import path
from tutorial01 import views

urlpatterns = [
path('users',views.UsersView.as_view()),
path(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 方法来根据不同请求方法执行不同的方法

mark

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
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.封装

  • 同一类方法封装到类中

    class File:
    // 文件增删改查方法
    def add:
    pass
    def delete:
    pass
    def update:
    pass
    def query:
    pass
    class DB
    // 数据库增删改查方法
    def add:
    pass
    def delete:
    pass
    def update:
    pass
    def query:
    class File:
    // 文件增删改查方法
    def add:
    pass
    def delete:
    pass
    def update:
    pass
    def query:
    pass
    class DB
    // 数据库增删改查方法
    def add:
    pass
    def delete:
    pass
    def update:
    pass
    def query:
    pass
  • 将数据封装到对象中

    class DB:
    // 文件增删改查方法
    def __init__(self, username, password):
    self.username = username
    self.password = password
    def add:
    pass
    def delete:
    pass
    def update:
    pass
    def query:
    pass
    obj1 = File('baimoc',class DB:
    // 文件增删改查方法
    def __init__(self, username, password):
    self.username = username
    self.password = password
    def add:
    pass
    def delete:
    pass
    def update:
    pass
    def query:
    pass
    obj1 = File('baimoc','123')

2.继承

避免重复编写共用的功能

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(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")

输出

Quit the server with CTRL-BREAK.
before
get
after

四、Django 中间件方法与流程

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

包括五个方法

  • process_request
  • process_response
  • process_view
  • process_exception
  • process_render_template

执行流程

mark