# 視圖層 from django.shortcuts import render, HttpResponse from django.views import View class CBVTest(View): # 經過調度(dispatch)分發請求 def dispatch(self, request, *args, **kwargs): pass super().dispatch(request, *args, **kwargs) pass def get(self, request): return render(request, 'cbv.html') def post(self, request): return HttpResponse('cbv post method') <!-- 模板層 --> <form action="/cbv/" method="post"> {% csrf_token %} <input type="text" name="usr"> <button type="submit">提交</button> </form> # 路由層 from app import views urlpatterns = [ url(r'^cbv/', views.CBVTest.as_view()), ]
models.pyhtml
from django.db import models class Book(models.Model): name = models.CharField(max_length=32) price = models.DecimalField(max_digits=5, decimal_places=2) class Meta: # 重命名 db_table = 'ob_book' verbose_name = "書籍" verbose_name_plural = verbose_name def __str__(self): return self.name
admin.pypython
from django.contrib import admin # Register your models here. from . import models admin.site.register(models.Book)
api/urls.pygit
from django.conf.urls import url from . import views urlpatterns = [ url(r'^books/', views.Book.as_view()), ]
urls.pydjango
from django.conf.urls import url, include from django.contrib import admin from api import urls urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^api/', include('api.urls')), ]
setting.pyapi
重點必需要進行註冊app
INSTALLED_APPS = [ .... 'api.apps.ApiConfig', 'rest_framework' ]
from rest_framework.views import APIView class Book(APIView): pass
from rest_framework.views import APIView from rest_framework.response import Response class Book(APIView): def get(self, request, *args, **kwargs): return Response('get ok') # 必需要返回數據,根據定義能夠返回字符串和字典 def post(self, request, *args, **kwargs): return Response({ 'status':0, 'msg':"post ok" })
from rest_framework.views import APIView from rest_framework.response import Response class Book(APIView): def get(self, request, *args, **kwargs): print(request) return Response('get ok') # 必需要返回數據,根據定義能夠返回字符串和字典
<rest_framework.request.Request object at 0x0000023E55D125F8>#這個不是原生的request,是通過封裝的request
驗證:2,3源碼分析
class Book(APIView): def get(self, request, *args, **kwargs): print(request) # 封裝作到徹底兼容 print(request._request.GET) # == print(request.GET) return Response('get ok') # 必需要返回數據,根據定義能夠返回字符串和字典 def post(self, request, *args, **kwargs): print(request) print(request._request.POST) print(request.POST) return Response({ 'status': 0, 'msg': "post ok" })
def post(self, request, *args, **kwargs): # 在請求頭中的變量的開頭都是用大寫的 print(request) print(request._request.POST) print(request.POST) print(request.META.get('HTTP_AUTH')) # 請求頭在請求發過來的時候會在前面拼接HTTP_而且參數會用大寫進行拼寫,get請求也是同樣的 return Response({ 'status': 0, 'msg': "post ok" })
def post(self, request, *args, **kwargs): print(request.query_params)#全部的拼接參數都放在query_params內,url連接請求攜帶的參數 print(request.data)#全部數據包數據都被解析到data中,post攜帶的參數 return Response({ 'status': 0, 'msg': "post ok" })
from rest_framework.views import APIView from rest_framework.response import Response from django.http.request import QueryDict class Book(APIView): def post(self, request, *args, **kwargs): print(request.query_params)#全部的拼接參數都放在query_params內,url連接請求攜帶的參數 print(request.data)#全部數據包數據都被解析到data中,post攜帶的參數 # 將數據包解析成字典的形式 if isinstance(request.data,QueryDict): print(request.data.dict()) print(request.query_params.dict()) print(request.data.dict()) return Response({ 'status': 0, 'msg': "post ok" })
源碼分析post
django只提供了一個View()類url
drf的APIView類:重寫了as_view(),但主體邏輯仍是調用父類View的as_view(),局部禁用了csrf認證,as_view(),主要就是作了局部禁用csrfspa
重點:全部繼承drf的基本視圖類APIView的視圖類,都不在作csrf認證校驗
drf的APIView類:重寫了dispatch(),在內部對request進行了二次封裝:self.initialize_request(request, *args, **kwargs)
內部核心:
走drf的Request初始化方法__init__:self._request = request
drf的Request的getter方法__getattr__:先從self._request反射取屬性,沒取到再衝drf的request中取
核心:request除了能夠訪問原wsgi協議的request全部內容,還能夠訪問 query_params、data
as_view()方法內 # 局部禁用csrf認證,全部的APIView類的視圖類都禁用了 return csrf_exempt(view)