Django REST Framework(簡稱DRF),是一個用於構建Web API的強大且靈活的工具包。python
先說說REST:REST是一種Web API設計標準,是目前比較成熟的一套互聯網應用程序的API設計理論。ajax
Fielding將他對互聯網軟件的架構原則,定名爲REST,即Representational State Transfer的縮寫。我對這個詞組的翻譯是」表現層狀態轉化」。若是一個架構符合REST原則,就稱它爲RESTful架構。因此簡單來講,RESTful是一種Web API設計規範,根據產品需求須要定出一份方便先後端的規範,所以不是全部的標準要求都須要遵循。django
Django FBV, function base view 視圖裏使用函數處理請求json
url(r‘^users/‘, views.users), from django.shortcuts import HttpResponse import json def users(request): user_list = ['lcg','superman'] return HttpResponse(json.dumps((user_list)))
Django CBV, class base view 視圖裏使用類處理請求後端
路由: url(r'^students/', views.StudentsView.as_view()), 視圖: from django.shortcuts import HttpResponse 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')
注意:restful
1.csrf校驗:架構
基於中間件的process_view方法實現對請求的csrf_token驗證app
2.不須要csrf驗證方法:函數
fbv:工具
from django.views.decorators.csrf import csrf_exempt @csrf_exempt def index(request): pass
cbv:
方式一
###方式一 from django.shortcuts import render,HttpResponse from django.views.decorators.csrf import csrf_exempt,csrf_protect from django.utils.decorators import method_decorator from django.views import View class Myview(View): @method_decorator(csrf_exempt) #必須將裝飾器寫在dispatch上,單獨加不生效 def dispatch(self, request, *args, **kwargs): return super(Myview,self).dispatch(request,*args,**kwargs) def get(self): return HttpResponse('get') def post(self): return HttpResponse('post') def put(self): return HttpResponse('put')
方式二:
from django.shortcuts import render,HttpResponse from django.views.decorators.csrf import csrf_exempt,csrf_protect from django.utils.decorators import method_decorator from django.views import View @method_decorator(csrf_exempt,name='dispatch')##name參數指定是dispatch方法 class Myview(View): def dispatch(self, request, *args, **kwargs): return super(Myview,self).dispatch(request,*args,**kwargs) def get(self): return HttpResponse('get') def post(self): return HttpResponse('post') def put(self): return HttpResponse('put')
請求到達Django會先執行Django中間件裏的方法,而後進行進行路由匹配。在路由匹配完成後,會執行CBV類中的as_view方法。
CBV中並無定義as_view方法,因爲CBV繼承自Django的View,因此會執行Django的View類中的as_view方法
Django的View類的源碼:
class View(object): """ Intentionally simple parent class for all views. Only implements dispatch-by-method and simple sanity checking. """ http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] def __init__(self, **kwargs): """ Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things. """ # Go through keyword arguments, and either save their values to our # instance, or raise an error. for key, value in six.iteritems(kwargs): setattr(self, key, value) @classonlymethod def as_view(cls, **initkwargs): """ Main entry point for a request-response process. """ for key in initkwargs: if key in cls.http_method_names: raise TypeError("You tried to pass in the %s method name as a " "keyword argument to %s(). Don't do that." % (key, cls.__name__)) if not hasattr(cls, key): raise TypeError("%s() received an invalid keyword %r. as_view " "only accepts arguments that are already " "attributes of the class." % (cls.__name__, key)) def view(request, *args, **kwargs): self = cls(**initkwargs) if hasattr(self, 'get') and not hasattr(self, 'head'): self.head = self.get self.request = request self.args = args self.kwargs = kwargs return self.dispatch(request, *args, **kwargs) view.view_class = cls view.view_initkwargs = initkwargs # take name and docstring from class update_wrapper(view, cls, updated=()) # and possible attributes set by decorators # like csrf_exempt from dispatch update_wrapper(view, cls.dispatch, assigned=()) return 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: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs) def http_method_not_allowed(self, request, *args, **kwargs): logger.warning( 'Method Not Allowed (%s): %s', request.method, request.path, extra={'status_code': 405, 'request': request} ) return http.HttpResponseNotAllowed(self._allowed_methods()) def options(self, request, *args, **kwargs): """ Handles responding to requests for the OPTIONS HTTP verb. """ response = http.HttpResponse() response['Allow'] = ', '.join(self._allowed_methods()) response['Content-Length'] = '0' return response def _allowed_methods(self): return [m.upper() for m in self.http_method_names if hasattr(self, m)]
上面實質上是路由裏面的那裏寫的as_view ,返回值是view 而view方法返回的是self.dispath
在dispatch方法中,把request.method轉換爲小寫再判斷是否在定義的http_method_names中,若是request.method存在於http_method_names中,則使用getattr反射的方式來獲得handler
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: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs)
在這裏的dispatch方法中,self指的是自定義的CBV類實例化獲得的對象,從CBV類中獲取request.method對應的方法,再執行CBV中的方法並返回
由此,能夠知道若是在Django項目中使用CBV的模式,實際上調用了getattr的方式來執行獲取類中的請求方法對應的函數
也就是說,繼承自View的類下的全部的方法本質上都是經過dispatch這個函數反射執行,若是想要在執行get或post方法前執行其餘步驟,能夠重寫dispatch