一、CBV / FBV处理请求的实现方式
1.一个是基于类写的,一个是基于函数写的,本质上区别不大。
2.推荐CBV方式来写,因为里边直接对请求方式进行了判断
# 基于FBV (function base view)
urlpatterns = [
url(r'^order/', views.order),
]
# 视图 view.py
def order(request):
if request.method == 'GET':
return HttpResponse('获取订单')
elif request.method == 'POST':
return HttpResponse('创建订单')
elif request.method == 'PUT':
return HttpResponse('更新订单')
elif request.method == 'DELETE':
return HttpResponse('删除订单')
# 基于CBV (class base view)
# 根据请求method的不同,进行对应dispatch,做不同操作
urlpatterns = [
url(r'^order/', views.OrderView.as_view()),
]
# 视图 view.py
class OrderView(View): # view内部实现请求分发机制(dispatch)
def get(self,request,*args,**kwargs):
return HttpResponse('获取订单')
def post(self,request,*args,**kwargs):
return HttpResponse('创建订单')
def put(self,request,*args,**kwargs):
return HttpResponse('更新订单')
def delete(self,request,*args,**kwargs):
return HttpResponse('删除订单')
二、CBV详解
CBV,基于反射实现根据请求方式不同,执行不同的方法。 (与装饰器功能特别相似)对请求进行检测dispatch分发,发到对应的post/get等方法
1.原理:
- `入口 as_view --> view(基于View基类) --> dispatch`
- `路由url --> view方法.as_view() --> dispatch方法(反射执行其他:GET/POST/DELETE/PUT)`
2.流程
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')
3.CBV对csrf的实现
@method_decorator(csrf_exempt)
- 在dispatch上添加(单独的请求添加无效)
# 方式一:
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 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')
三、注意点
1. CSRF基于Django的中间件的实现
- Django中间件(最多五个)
- process_request
- process_view
- process_response
- process_exception
- process_render_template - Django中间件的执行顺序?
- 使用中间件做啥?
- 权限
- 用户登录验证
- Django的CSRF是如何实现的?
- process_view方法(为什么在这?只有到这才能找到那个装饰器函数,才能进行处理)
2. CSRF两种配置方式
# 情况一(全局配置认证,个别函数不配置):
MIDDLEWARE = [
'django.middleware.csrf.CsrfViewMiddleware', # 全站使用csrf认证
]
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt # 该函数无需认证
def users(request):
user_list = ['alex','oldboy']
return HttpResponse(json.dumps((user_list)))
# 情况二(全局不配置认证,个别配置):
MIDDLEWARE = [
#'django.middleware.csrf.CsrfViewMiddleware', # 注掉这个中间件,表示全站不使用csrf认证
]
from django.views.decorators.csrf import csrf_exempt
@csrf_protect # 该函数需认证
def users(request):
user_list = ['alex','oldboy']
return HttpResponse(json.dumps((user_list)))