A、に従いDRF使用
インストールDRF:
pip3 install djangorestframework
アプリのsettings.py登録:
INSTALLED_APPS = [ ... 'rest_framework' ]
CBVは、ベースのインタフェース仕様が安らか会う完成しました
# 视图层 from rest_framework.views import APIView from rest_framework.response import Response # CBV接口 class Test(APIView): def get(self,request,*args,**kwargs): print(request.GET) print(request.META) return Response({ 'status': 0, 'msg': 'get ok' }) def post(self,request,*args,**kwargs): print(request.POST) return Response({ 'status': 0, 'msg': 'post ok', })
# 路由层 urlpatterns = [ url(r'^api/', views.Test.as_view()), ]
二、DRF CBVソースコード解析
- まず、ルーティング層の登録CBV、CBVのas_viewによって実施される方法() 、同じ方法及びCBVを実現ジャンゴ。しかし、DRFは、CBVにおけるいくつかの他のプロセスを行いました。例えば、彼らはまだあるもののビューas_viewコールを取得するには親クラスが、ローカル無効にCSRFの認定のリターン
csrf_exempt(view)
- 要求が来たとき、ビュー関数マッピング関係をルーティングするマッチングの配信要求が成功した入る
dispatch()
方法。 dispatch()
インナー方法配布前に完全に方法の実装の観点から:- 第2のパッケージ要求:self.initialize_request(要求、* argsを、** kwargsから)
- 三認定:self.initial(要求、* argsを、 ** kwargsから)
- 要求はビューを処理された後の方法を示します。
- 珍しい治療:self.handle_exception(EXC)
- 二次封装応答:self.finalize_response(要求、応答、* argsを、** kwargsから)
'''rest_framework/views.py -> class APIView(view):中'''
@classmethod
def as_view(cls, **initkwargs):
if isinstance(getattr(cls, 'queryset', None), models.query.QuerySet):
def force_evaluation():
raise RuntimeError(
'Do not evaluate the `.queryset` attribute directly, '
'as the result will be cached and reused between requests. '
'Use `.all()` or call `.get_queryset()` instead.'
)
cls.queryset._fetch_all = force_evaluation
# 调用父类as_view方法返回view对象
view = super().as_view(**initkwargs)
view.cls = cls
view.initkwargs = initkwargs
return csrf_exempt(view)
'''rest_framework/views.py -> class APIView(view):中'''
def dispatch(self, request, *args, **kwargs):
self.args = args
self.kwargs = kwargs
# 二次封装request
request = self.initialize_request(request, *args, **kwargs)
self.request = request
self.headers = self.default_response_headers # deprecate?
try:
# 三大认证
self.initial(request, *args, **kwargs)
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
response = handler(request, *args, **kwargs)
except Exception as exc:
# 出现异常的处理
response = self.handle_exception(exc)
# 二次封装response
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
注: DRFソースについての最も次の発送方法からスタートすることになるが、分析を開始します
第三に、要求モジュールのソースコード解析
APIViewカテゴリのDRF:as_viewを書き直し()が、主なロジックはまだas_viewの親ビューを(呼び出し)、ローカル認証が無効になっCSRFです
キー:すべてはCSRF認定チェックをしていない、ビュークラスDRFベースのビュークラスを継承しAPIView
クラスDRF APIView:ディスパッチをオーバーライド()、第二のパッケージの内部に要求しました
# 二次封装request request = self.initialize_request(request, *args, **kwargs)
内部ソース解析方法initialize_request
- オブジェクトの例としては、Requestクラスを返しました。
- 要求クラス
__init__
のメソッド元のrequest
配置self._request
に - すべてのスプライシングパラメータはquery_paramsに解析され、すべてのデータパケットは、データに解析されることにより、
@property
属性データの属性をパッケージングする方法にデコレータ。 - query_paramsとデータ型のQueryDict属する缶().dictによる天然型辞書に
内部要求クラスが実装する。インターセプト法
__getattr__
_requestのコンテンツに直接取られる値
# CBV接口
class Test(APIView):
def get(self,request,*args,**kwargs):
print(request._request.GET) # 直接找原来的request
print(request.GET) # 通过内部的getattr来找
print(request.META) # 通过内部的getattr来找
# QueryDict转化为原生dict
print(request.query_params.dict())
# 数据包数据
print(request.data)
return Response({
'status': 0,
'msg': 'get ok'
})
def post(self,request,*args,**kwargs):
# 通过内部的getattr来找
print(request.POST)
# QueryDict转化为原生dict
print(request.query_params.dict())
print(request.data.dict())
return Response({
'status': 0,
'msg': 'post ok',
})