一 类中绑定方法的传参,不需要self
class Foo(object): def __init__(self,name): self.name = name def foo(self,x): self.x = x f = Foo('sccc') func = f.foo func('miracle') print(f.x)
输出:
miracle
同样
class OrderView(View): def dispatch(self, request, *args, **kwargs): print(self.request.method) func = getattr(self,request.method.lower()) print(func) ret = func(request,*args,**kwargs) return ret def get(self,request,*args,**kwargs): return HttpResponse('get') def post(self,request,*args,**kwargs): return HttpResponse('post') def delete(self,request,*args,**kwargs): return HttpResponse('delete') def update(self,request,*args,**kwargs): return HttpResponse('update')
输出: 注意,request.method 会将get,post等变为大写。
GET [05/Mar/2018 17:09:12] "GET /orders/ HTTP/1.1" 200 3 <bound method OrderView.get of <app01.views.OrderView object at 0x000001215CF09E48>>
二 super 与 mro顺序
为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
class A: def xx(self): print('xxx') super().xx() print(super()) class C: def xx(self): print('cc') print(super()) class B(A,C): pass b = B() b.xx() print(B.mro())
输出:
xxx cc <super: <class 'C'>, <B object>> <super: <class 'A'>, <B object>> [<class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>]
从 父类A中,super(),继续按照mro顺序查找。
同样的道理。
自定义父类 MyBaseView,子类 StudentView 继承MyBaseView和系统导入的View。 实现在原有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 StudentView(MyBaseView,View): def get(self,request,*args,**kwargs): return HttpResponse('get') def post(self,request,*args,**kwargs): return HttpResponse('post') def delete(self,request,*args,**kwargs): return HttpResponse('delete') def update(self,request,*args,**kwargs): return HttpResponse('update')
三 csrf_exempt,csrf_protect
from django.views.decorators.csrf import csrf_exempt,csrf_protect
可以单独对某个FBV,或CBV进行csrf 设置。
FBV的设置比价简单,直接加装饰器
@csrf_protect # 该函数需认证 def users(request): user_list = ['alex','oldboy'] return HttpResponse(json.dumps((user_list)))
@csrf_exempt # 该函数无需认证 def users(request): user_list = ['alex','oldboy'] return HttpResponse(json.dumps((user_list)))
CBV相对复杂一些。
方式一: from django.views.decorators.csrf import csrf_exempt,csrf_protect from django.utils.decorators import method_decorator class StudentsView(View): @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): return super(StudentsView,self).dispatch(request, *args, **kwargs) 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')
方式二: from django.views.decorators.csrf import csrf_exempt,csrf_protect from django.utils.decorators import method_decorator @method_decorator(csrf_exempt,name='dispatch') class StudentsView(View): def dispatch(self, request, *args, **kwargs): return super(StudentsView,self).dispatch(request, *args, **kwargs) 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')
四 FBV,CBV
CBV,基于反射实现根据请求方式不同,执行不同的方法。
原理:
url -> view方法 -> dispatch方法(反射执行其他:GET/POST/DELETE/PUT)
流程:
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')