FBV的意思是function base view,意思就是在views.py中写函数。我们常用的urls.py里面的路径对应views里面的函数。
CBV的意思是class base view,意思就是在views.py中写类,urls.py里面的路径对应一个类。
1. 列表生成式:
class Foo: pass class Bar: pass v = [] for i in [Foo,Bar]: obj = i() v.append(obj) v = [item() for item in [Foo,Bar]] # v是一个实例化对象列表
2. 面向对象
封装:
a. 对同一类方法封装到类中(文件增删改查方法,数据库的增删改查方法 )
b. 将数据封装到对象中
class File: def __init__(self,a1,a2): self.a1 = a1 self.xxx = a2 def get:... def delete:... def update:... def add:... obj1 = File(123,666) obj2 = File(456,999)
扩展:
class Request(object): def __init__(self,obj): self.obj = obj @property def user(self): return self.obj.authticate() class Auth(object): def __init__(self,name,age): self.name = name self.age = age def authticate(self): return self.name class APIView(object): def dispatch(self): self.f2() def f2(self): a = Auth(‘alex‘,18) req = Request(a) print(req.user) obj = APIView() obj.dispatch() # 打印alex
3. CBV基于反射实现根据请求方式的不同,执行不同的方法,方法包括:
http_method_names = [‘get‘, ‘post‘, ‘put‘, ‘patch‘, ‘delete‘, ‘head‘, ‘options‘, ‘trace‘]
原理:url --> view方法 --> dispatch方法
views.py
# 如下是FBV在视图文件中写函数 def users(request): user_list = [‘alex‘,‘oldboy‘] return HttpResponse(json.dumps((user_list))) # 如下是CBV在视图文件中写类,需要注意类必须继承View这个父类。同时类名按照规范要以View结尾。 from django.views import View class StudentsView(View): def get(self,request,*args,**kwargs): return HttpResponse(‘GET‘) def post(self, request, *args, **kwargs): return HttpResponse(‘POST‘) def put(self, request, *args, **kwargs): return HttpResponse(‘PUT‘) def delete(self, request, *args, **kwargs): return HttpResponse(‘DELETE‘)
urls.py
re_path(‘^students/‘, views.StudentsView.as_view()),
如上程序执行逻辑首先用户通过url访问到路径students/,触发视图函数views中StudentsView类的as_view()方法,但是我们看到该StudentsView没有as_view()方法,于是去他的父类View找。
def as_view(cls, **initkwargs): # 省略前面的判断过程 def view(request, *args, **kwargs): # 省略前面的判断过程 return self.dispatch(request, *args, **kwargs) return view # 可以看到该函数调用的是dispath函数
于是我们继续找到dispatch函数:
def dispatch(self, request, *args, **kwargs): # http_method_names = [‘get‘, ‘post‘, ‘put‘, ‘patch‘, ‘delete‘, ‘head‘, ‘options‘, ‘trace‘] if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs) # 如果request.method.lower()在http_method_names中,则执行下面的handler,去获取request方法,若是没有获取到就调用http_method_not_allowed抛出异常。如是获取到了就返回这个方法函数。例如: # post(request, *args, **kwargs) get(request, *args, **kwargs),注意都是小写,因为用了lower关键字,将方法编程了小写。 # 若是在执行handler函数前后加一些动作,则可以完成例如用户认证,或者限流等操作。 # 所以接下来我们尝试改写dispatch函数。
改写dispatch函数,由于dispatch函数在父类中,我们在当前类中写一个相同的dispatch函数将被优先调用。
class StudentsView(View): def dispatch(self, request, *args, **kwargs): print(‘before‘) # 在请求处理之前可以进行的操作,例如可以做认证等 ret = super(StudentsView,self).dispatch(request, *args, **kwargs) print(‘after‘) # 在请求处理之后可以进行的操作,可以添加访问记录,用来做限流 return ret def get(self,request,*args,**kwargs): return HttpResponse(‘GET‘) def post(self, request, *args, **kwargs): return HttpResponse(‘POST‘) def put(self, request, *args, **kwargs): return HttpResponse(‘PUT‘) def delete(self, request, *args, **kwargs): return HttpResponse(‘DELETE‘)
from django.views import View class MyBaseView(object): def dispatch(self, request, *args, **kwargs): print(‘before‘) ret = super(MyBaseView,self).dispatch(request, *args, **kwargs) print(‘after‘) return ret class StudentsView(MyBaseView,View): # 注意要把自己写的父类写在前面,前面的优先 def get(self,request,*args,**kwargs): print(‘get方法‘) return HttpResponse(‘GET‘) def post(self, request, *args, **kwargs): return HttpResponse(‘POST‘) def put(self, request, *args, **kwargs): return HttpResponse(‘PUT‘) def delete(self, request, *args, **kwargs): return HttpResponse(‘DELETE‘) class TeachersView(MyBaseView,View): def get(self,request,*args,**kwargs): return HttpResponse(‘GET‘) def post(self, request, *args, **kwargs): return HttpResponse(‘POST‘) def put(self, request, *args, **kwargs): return HttpResponse(‘PUT‘) def delete(self, request, *args, **kwargs): return HttpResponse(‘DELETE‘)
原文:https://www.cnblogs.com/tortoise512/p/15177566.html