請求模塊

請求模塊

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.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'
]

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

請求模塊源碼分析

源碼分析post

  1. django只提供了一個View()類url

  2. drf的APIView類:重寫了as_view(),但主體邏輯仍是調用父類View的as_view(),局部禁用了csrf認證,as_view(),主要就是作了局部禁用csrfspa

  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)

相關文章
相關標籤/搜索