一、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)))