请求模块

请求模块

CBV源码分析

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

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.py

from django.contrib import admin
# Register your models here.
from . import models
admin.site.register(models.Book)

api/urls.py

from django.conf.urls import url
from . import views
urlpatterns = [
    url(r'^books/', views.Book.as_view()),
]

urls.py

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.py

重点必须要进行注册

INSTALLED_APPS = [
	....
    'api.apps.ApiConfig',

    'rest_framework'
]

请求1

from rest_framework.views import APIView


class Book(APIView):
    pass

请求2

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"
        })

请求模块request

特点:

  1. drf的request是在wsgi的request基础上再次封装
  2. wsgi的request作为drf的request一个属性:_request
  3. 新的request对旧的request做了完全兼容
  4. 新的request对数据解析更规范化:所有的拼接参数都解析到query_params中,所有数据包数据都被解析到data
    • query_params和data属于QueryDict类型,可以 .dict() 转化成原生dict类型
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"
        })

post请求头

  1. 请求头在请求发过来的时候会在前面拼接HTTP_并且参数会用大写进行拼写,get请求也是一样的
    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"
        })

请求模块源码分析

源码分析

  1. django只提供了一个View()类

  2. drf的APIView类:重写了as_view(),但主体逻辑还是调用父类View的as_view(),局部禁用了csrf认证,as_view(),主要就是做了局部禁用csrf

  3. 重点:所有继承drf的基本视图类APIView的视图类,都不在做csrf认证校验

  4. 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)

原文地址:https://www.cnblogs.com/SkyOceanchen/p/11895473.html