# 视图层 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)