web應用模式、API介面、介面測試工具postman、如何在瀏覽器中測試、restful規範、序列化反序列化、基於Django原生編寫五個介面、drf介紹和快速使用、drf之APIView源碼分析

来源:https://www.cnblogs.com/wurenyao/archive/2023/05/17/17406839.html
-Advertisement-
Play Games

一、web應用模式 Django框架就是一種web框架,專門用來寫web項目,之前學的,寫的BBS項目,圖書管理系統,用的都是前後端混合開發 -後端人員,寫後端,也要寫【模板語法】 》xx.html的python代碼 -全棧開發-->前後端混合時代,比較多 從今天開始,學的是前後端分離 -後端人員, ...


目錄

一、web應用模式

  • Django框架就是一種web框架,專門用來寫web項目,之前學的,寫的BBS項目,圖書管理系統,用的都是前後端混合開發
	-後端人員,寫後端,也要寫【模板語法】---》xx.html的python代碼
    -全棧開發-->前後端混合時代,比較多
  • 從今天開始,學的是前後端分離
	-後端人員,一點前端都不需要動,只需要寫介面即可
    -全棧開發---》web後端,前端框架(vue,react)

在開發Web應用中,有兩種應用模式:
1.前後端不分離客戶端看到的內容和所有界面效果都是由服務端提供出來的

image

image

2.前後端分離【把前端的界面效果(htmlcssjs分離到另一個服務端,python服務端只需要返回數據即可)】

前端形成一個獨立的網站,服務端構成一個獨立的網站

image

image

二、API介面

為了在團隊內部形成共識、防止個人習慣差異引起的混亂,我們需要找到一種大家都覺得很好的介面實現規範,而且這種規範能夠讓後端寫的介面,用途一目瞭然,減少雙方之間的合作成本【前後端合作】
API概念
API:應用程式介面(API:Application Program Interface

應用程式介面(API:application programming interface)是一組定義、程式及協議的集合,通過 API 介面實現電腦軟體之間的相互通信。API 的一個主要功能是提供通用功能集。程式員通過使用 API 函數開發應用程式,從而可以避免編寫無用程式,以減輕編程任務
簡單來說就是通過網路,規定了前後端信息交互規定的URL鏈接,也就是前後端信息交互的媒介

    http://127.0.0.1/books/   
	點贊,點踩  就是API介面
  • URL:長得像返回數據的URL鏈接
    https://api.map.baidu.com/place/v2/search

  • 請求方式:getpostputpatchdelete
    採用get方式請求上方介面

  • 請求參數:jsonxml格式的key-value類型數據
    ak6E823f587c95f0148c19993539b99295
    region:上海
    query:肯德基
    output:json

	-早些年 前後端交互使用xml格式----》ajax:非同步JavaScript和XML
	-後來,隨著json格式的出現,成了主流,直到現在
	-以後:一定會出現,比json更高效的交互格式,更安全
  • 響應結果:json或xml格式的數據
    • 上方請求參數的output參數值決定了響應數據的格式
    • 數據
# xml格式
https://api.map.baidu.com/place/v2/search?ak=6E823f587c95f0148c19993539b99295&region=%E4%B8%8A%E6%B5%B7&query=%E8%82%AF%E5%BE%B7%E5%9F%BA&output=xml
'''中文會變成上面的樣式,上下兩個url是一樣的意思'''
https://api.map.baidu.com/place/v2/search?ak=6E823f587c95f0148c19993539b99295&region=上海&query=肯德基&output=xml
#json格式
https://api.map.baidu.com/place/v2/search?ak=6E823f587c95f0148c19993539b99295&region=%E4%B8%8A%E6%B5%B7&query=%E8%82%AF%E5%BE%B7%E5%9F%BA&output=json

https://api.map.baidu.com/place/v2/search?ak=6E823f587c95f0148c19993539b99295&region=上海&query=肯德基&output=json

'''下方是返回的值'''
{
    "status":0,
  	"message":"ok",
    "results":[
        {
            "name":"肯德基(羅餐廳)",
            "location":{
                "lat":31.415354,
                "lng":121.357339
            },
            "address":"月羅路2380號",
            "province":"上海市",
            "city":"上海市",
            "area":"寶山區",
            "street_id":"339ed41ae1d6dc320a5cb37c",
            "telephone":"(021)56761006",
            "detail":1,
            "uid":"339ed41ae1d6dc320a5cb37c"
        }
      	...
		]
}

三、介面測試工具postman

postman介紹

作為後端,寫好了介面,我們自己要測試通過,再給別人用。

而後端測試人員需要測試API介面的時候,總不可能在瀏覽器裡面試用吧,所以有了專業的介面測試工具Postman

	-瀏覽器只能發送get請求,不能自動發送post,delete請求
    -postman---》開源軟體,只是谷歌瀏覽器的插件,越做好好,後來可以按裝到操作系統上,再後來,收費
    -postwoman
    -很多很多其他的,不同公司用的也可能不一樣,你只需要明白一個點,這個工具只是用來發送http請求

postman下載與使用

1、官方下載
https://www.postman.com/downloads/?utm_source=postman-home----》Postman-win64-Setup.exe
2、安裝時,雙擊即可,馬上就會出現下圖界面
image
3、使用講解

打開一個新的測試頁面後界面如下,返回數據的視窗在沒有發送請求之前是空的。
image
點擊界面中間的Body,可以選擇發送請求的方式,需要註意在使用form-data請求方式,即用form表單傳輸文件的時候,需要手動選擇傳輸的數據類型
image

image

這裡返回的結果
image

四、如何在瀏覽器中測試

我們需要再settings.py文件中註冊rest_framework才能在瀏覽器中進行介面測試

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.App01Config',
    'rest_framework',
]

五、restful規範(重要)

概念
REST全稱是Representational State Transfer,中文意思是表述(編者註:通常譯為表徵性狀態轉移)。 它首次出現在2000年Roy Fielding的博士論文中

RESTful是一種定義Web API介面的設計風格,尤其適用於前後端分離的應用模式中
這種風格的理念認為後端開發任務就是提供數據的,對外提供的是數據資源的訪問介面,所以在定義介面時,客戶端訪問的URL路徑就表示這種要操作的數據資源

事實上,我們可以使用任何一個框架都可以實現符合restful規範的API介面

十條規範

   -1 數據的安全保障,通常使用https(http+ssl/tsl)協議
        -url鏈接一般都採用https協議進行傳輸
        -採用https協議,可以提高數據交互過程中的安全性
        
   -2 介面中帶api標識
		-https://api.lqz.com/books(可以寫在功能變數名稱中)
        -https://www.lqz.com/api/books(也可以寫在路由中)    咱們用這個
            
   -3 多版本共存,路徑中帶版本信息
		-https://api.lqz.com/v1/login
        -https://api.lqz.com/v2/login
		-https://www.lqz.com/api/v1/login
        -https://www.lqz.com/api/v2/login
            
   -4 數據即是資源,均使用名詞,儘量不出現動詞(最核心的)
		-介面一般都是用於完成前後臺數據的交互,交互的數據我們稱之為資源
    	-介面形式如下
            https://api.baidu.com/users
            https://api.baidu.com/books
        -特殊的介面可以出現動詞,因為這些介面一般沒有一個明確的資源,或是動詞就是介面的核心含義、				https://api.baidu.com/login
        
        
   -5 資源操作由請求方式決定(method)
		-操作資源一般都會涉及到增刪改查,我們提供請求方式來標識增刪改查動作
        https://api.baidu.com/books    - get請求:獲取所有書(獲取所有)
        https://api.baidu.com/books/1  - get請求:獲取主鍵為1的書(獲取一條)
        https://api.baidu.com/books    - post請求:新增一本書書(新增一條)
        https://api.baidu.com/books/1  - put請求:修改主鍵為1的書(整體修改一條)
        https://api.baidu.com/books/1  - patch請求:修改主鍵為1的書(局部修改一條)
        'ps:patch用的不多,一般用put即可'
        https://api.baidu.com/books/1  - delete請求:刪除主鍵為1的書(刪除一條)
            
            
   -6 在請求地址中帶過濾條件
    https://api.example.com/v1/zoos?limit=10:指定返回記錄的數量
    https://api.example.com/v1/zoos?offset=10:指定返回記錄的開始位置
    https://api.example.com/v1/zoos?page=2&per_page=100:指定第幾頁,以及每頁的記錄數
    https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回結果按照哪個屬性排序,以及排序順序
    https://api.example.com/v1/zoos?animal_type_id=1:指定篩選條件
    
    
   -7 響應中狀態碼:兩套
		-http響應狀態碼:1xx:請求正在處理,2xx:成功響應,3xx:重定向,4xx:客戶端錯誤,5xx:服務端錯誤
    '常見的需要記住'
    	響應狀態碼2XX		200:常規請求		201:創建成功
	 	響應狀態碼3XX		301:永久重定向	302:暫時重定向
	 	響應狀態碼4XX		403:請求無許可權	404:請求路徑不存在	405:請求方法不存在
	 	響應狀態碼5XX		500:伺服器異常
    		-https://blog.csdn.net/li_chunlong/article/details/120787872
        -公司內部規定的響應狀態碼,放在響應體中
        	{code:0}   咱們後期一般使用100  101 102這種
            
            
    -8 返回數據中帶錯誤信息
    	{
            code:0
    		msg: "ok/用戶名錯誤"
		}
        
        
    -9 返回的結果應該符合以下規範---》好多公司不遵循這個
        GET 獲取所有數據:返回資源對象的列表(數組)[{name:紅樓夢,price:99},{name:紅樓夢,price:99},{name:紅樓夢,price:99}]
        GET 單個對象:返回單個資源對象:{name:紅樓夢,price:99}
        POST 新增對象:返回新生成的資源對象:{name:西游記,price:99}
        PUT 修改對象:返回完整的資源對象 :{name:西游記,price:100}
        DELETE 刪除:返回一個空文檔 
        
        
    -10 響應數據中帶連接
    		# Hypermedia API,RESTful API最好做到Hypermedia,即返回結果中提供鏈接,連向其他API方法,使得用戶不查文檔,也知道下一步應該做什麼
		{
		  	"status": 0,
		  	"msg": "ok",
		  	"results":[
		        {
		            "name":"肯德基(羅餐廳)",
		            "img": "https://image.baidu.com/kfc/001.png"
		        }
		      	...
				]
		}
	
	比較好的介面返回
		# 響應數據要有狀態碼、狀態信息以及數據本身
		{
		  	"status": 0,
		  	"msg": "ok",
		  	"results":[
		        {
		            "name":"肯德基(羅餐廳)",
		            "location":{
		                "lat":31.415354,
		                "lng":121.357339
		            },
		            "address":"月羅路2380號",
		            "province":"上海市",
		            "city":"上海市",
		            "area":"寶山區",
		            "street_id":"339ed41ae1d6dc320a5cb37c",
		            "telephone":"(021)56761006",
		            "detail":1,
		            "uid":"339ed41ae1d6dc320a5cb37c"
		        }
		      	...
				]
		}

六、序列化反序列化

api介面開發,最核心最常見的一個過程就是序列化,所謂序列化就是把【數據轉換格式】,序列化可以分兩個階段:

序列化: 把我們識別的數據轉換成指定的格式提供給別人

-字典,列表------》json格式存到文件中了
	-例如:我們在django中獲取到的數據預設是模型對象,但是模型對象數據無法直接提供給前端或別的平臺使用,所以我們需要把數據進行序列化,變成字元串或者json數據,提供給別人
	-read

反序列化:把別人提供的數據轉換/還原成我們需要的格式

-例如:前端js提供過來的json數據,對於python而言就是字元串,我們需要進行反序列化換成模型類對象,這樣我們才能把數據保存到資料庫中。
    -write

七、基於Django原生編寫五個介面

# 以後寫的介面,基本上都是五個介面及其變形
	-查詢所有
	-查詢單個
	-新增一個
	-修改一個
	-刪除一個

# 基於books單表為例,寫五個介面
	-創建book表
	-表遷移
	-錄入假數據:直接錄,後臺管理錄
	-寫查詢所有介面----》遵循restful規範,使用cbv
	-新增一條數據-----》
	-查詢一條
	-修改一條:put提交的數據,不能從request.POST中取
	-刪除一條

models.py

form django.db import models

class Book(models.Model):
	name = models.CharField(max_length=32)
	price = models.CharField(max_length=32)
	publish = models.CharField(max_length=32)

urls.py

urlpatterns = [
	path('admin/', admin.site.urls),
	path('api/v1/books/', views.BookView.as_view()),
	path('api/v1/books/<int:pk>/', views.BookDetailView.as_view()),
]

views.py

from django.shortcuts import render,HttpResponse,redirect

from django.http import JsonResponse
from .models import Book	# 相對導入
from django.views import View

import json

class BookView(View):
	# 查詢所有
	def get(self, request):
		# 查詢出所有的圖書,queryset對象,不能直接給前端
		books = Book.objects.all()
		# 轉成json格式,給前端
		# 把quer對象轉成列表,然後再使用JsonResponse
		book_list = []
		for book in books:
			book_list.append({'name': book.name, 'price': book.price, 'publish': book.publish})
		# 擴展做瞭解
		# return HtpResponse(json.dumps(book_list, ensure_ascii=False))	# 指定ensure_ascii為false,前端就顯示中文了
		return JsonResponse(book_list, safe=False, json_dumps_params={'ensure_ascii': False})	# JsonRsponse只能放字典或列表
		
	# 薪增一個(只能使用urlencoded或form-data編碼,使用json形式編碼不行,因為json格式編碼提交的數據,不能從request.POST中取,從body中)
	def post(self, request):
		# 取出前端傳入的數據
		name = request.POST.get('name')
		price = reqeust.POST.get('price')
		publish = request.POST.get('publish')
		# 存到資料庫中
		book = Book.objects.create(name=name, price=price, publish=publish)
		# 返回新增的對象字典
		return JsonResponse({'name': book.name, 'price': book.price, 'publish': book.publish})

class BookDetailView(View):
	def get(self, request, pk):
		book = Book.objectsfilter(pk=pk).first()
		# book模型對象轉成字典,使用JsonResponse返回
		return JsonResponse({'id': book.id, 'name': book.name, 'price': book.price, 'publish': book.publish})
	
	def put(self, request, pk):	# request.POST只能取post提交的urlencoded或form-data編碼數據,put提交的取不到
		# 查到要改的
		book = Book.objects.filter(pk=pk).first()
		# 取出前端傳入的數據,修改完,保存----》存在問題,因為put提交的取不到
		# book.name = request.POST.get('name')
		# book.price = request.POST.get('price')
		# book.publish = request.POST.get('publish')
		# book.save()
		
		# 前端使用json格式提交,自己保存
		print(request.body)
		book_dict=json.loads(request.body)
		book.name = book_dict.get('name')
		book.price = book_dict.get('price')
		book_publish = book_dict.get('publish')
		book.save()
		
		return JsonResponse({'id': book.id, 'name': book.name, 'price': book.price, 'publish': book.publish})
		
	def delete(self, request, pk):
		Book.objects.filter(pk=pk).delete()
		return JsonResponse(data={})

八、drf介紹和快速使用

概念

核心思想: 縮減編寫api介面的代碼

Django REST framework是一個建立在Django基礎之上的Web 應用開發框架,可以快速的開發REST API介面應用。在REST framework中,提供了序列化器Serialzier的定義,可以幫助我們簡化序列化與反序列化的過程,不僅如此,還提供豐富的類視圖、擴展類、視圖集來簡化視圖的編寫工作。REST framework還提供了認證、許可權、限流、過濾、分頁、介面文檔等功能支持。REST framework提供了一個API 的Web可視化界面來方便查看測試介面。

官方文檔:https://www.django-rest-framework.org/

github: https://github.com/encode/django-rest-framework/tree/master

特點(瞭解一下)

  • 提供了定義序列化器Serializer的方法,可以快速根據 Django ORM 或者其它庫自動序列化/反序列化;
  • 提供了豐富的類視圖、Mixin擴展類,簡化視圖的編寫;
  • 豐富的定製層級:函數視圖、類視圖、視圖集合到自動生成 API,滿足各種需要;
  • 多種身份認證和許可權認證方式的支持;[jwt]
  • 內置了限流系統;
  • 直觀的 API web 界面;
  • 可擴展性,插件豐富

安裝

# djangorestframework:  drf 幫助我們快速的實現符合restful規範的介面

# django 最新 4.x ,一般都會用最新版的上一版3.x
# drf最新支持到djagno 3.x ,最新不支持2.x
# 安裝drf
	pip3 install djangorestframework -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com/simple/
    # 由於你是django2.x 它發現它不支持,它會自動寫在dajgno,安裝最新的django 4.x

使用drf編寫五個介面

註意:url的末尾必須要寫斜杠符號,不然會報錯
urls.py

from app01.views import BookView
from rest_framework.routers import SimpleRouter
router = SimpleRouter
router = SimpleRouter()
router.register('books', BookView, 'books')
urlpatterns = [
	path('admin/', admin.site.urls),
]
# 兩個列表相加 [1,2,4] + [6,7,8]=
urlpatterns += router.urls

views.py

form .serializer import BookSerializer
from rest_framework.viewsets import ModelViewSet
class BookView(ModelViewSet):
	queryset = Book.objects.all()
	serializer_class = BookSerializer

serializer.py

from rest_framework import serializers
form .models import Book
class BookSerializer(serializers.ModelSerializer):
	class Meta:
	model = Book
	fields = '__all__'

九、drf之APIView源碼分析

基於APIView寫五個介面

urls.py

urlpatterns = [
	path('books/', BookView.as_view()),
	path('books/<int:pk>/', BookDetailView.as_view()),
]

views.py

form rest_framework.views import APIView	# APIView繼承了Django原來的View
from .serializer import BookSerializer
from rest_framework.response import Response

class BookView(APIView):
	# 查詢所有
	def get(self, request):
		book_list = Book.objects.all()
		# drf提供了序列化類
		ser = BookSerializer(instance=book_list, many=True)	# 序列化
		return Response({'code': 100, 'msg': '成功', 'result': ser.data})
	
	def post(self, request):
		ser = BookSerializer(data=request.data)	# 反序列化
		if ser.is_valid():	# 數據校驗---》有些不合法禁止
			ser.save()	# 保存到資料庫中
		return Response({'code': 100, 'msg': '成功'})

class BookDetailView(APIView):
	# # 查詢單條
	def get(self, request, pk):
		book = Book.objects.filter(pk=pk).first()
		ser = BookSerializer(instance=book,many=False)	# 序列化
		return Response({'code': 100, 'msg': '成功', 'result': ser.data})
	# 修改一條
	def put(self, request, pk):
		book = Book.objects.filter(pk=pk).first()
		ser = BookSerializer(instance=book,data=request.data)	# 反序列化
		if ser.is_valid():	# 數據校驗---》有些不合法禁止
			ser.save()	# 保存到資料庫中
		return Response({'code': 100, 'msg': '成功'})
	def delete(self, request, pk):
		Book.objects.filter(pk=pk).delete()
		return Response({'code': 100, 'msg': '刪除成功'})

serializer.py

from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
	class Meta:
		model = Book
		fields = '__all__'

CBV源碼分析

# cbv寫法:
	1 視圖中寫視圖類,繼承View,寫跟請求方式同名的方法
    	class BookView(View):
            def get(self,request):
                return 四件套
     2 在路徑用寫
    	path('books/', BookView.as_view())
        
        
        
# 如上寫法,為什麼能夠執行

# 前置條件:前端請求,一旦路徑匹配成功,就會執行  BookView.as_view()(request傳入,)
# 入口在  BookView.as_view()--->執行結果---》View中有個as_view類的綁定方法
    @classmethod
    def as_view(cls, **initkwargs):
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            res=self.dispatch(request, *args, **kwargs)
            return res
        return view
    
# 執行結果是view 的記憶體地址: 請求來了,執行view(request)
	path('books/', view)
    
# 執行 View類中的as_view方法中的內層的view函數,路由匹配成功,本質是在執行
	self.dispatch(request, *args, **kwargs)
    # self是誰的對象?BookView的對象
    # 去BookView中dispatch,找不到,去父類,View中找到了
    
    
# View這個類的dispatch
    def dispatch(self, request, *args, **kwargs):
        # request.method.lower() 如果是get請求,  ‘get’ 在這個列表裡面
        if request.method.lower() in self.http_method_names:
            # handler=getattr(BookView的對象,'get')   
            # handler就是BookView類中的get方法
            handler = getattr(self, request.method.lower())
        else:
            handler = self.http_method_not_allowed
        # 執行 BookView類中的get方法 (request)
        return handler(request, *args, **kwargs)
    
# 最終本質跟寫fbv的執行流程一樣
# 最終結論:什麼請求方式,就會執行視圖類中的什麼方法
	-本身請求來了,匹配成功,會執行view(request)
	def view(request, *args, **kwargs):
		return self.dispatch(request, *args, **kwargs)
	-self.dispatch  View類的方法
	def dispatch(self, request, *args, **kwargs):
		# request.method請求方式轉成小寫,必須在列表中才能往下走
		if request.method.lower() in self.http_method_names:
			# 反射,去self【視圖類的對象:BookView】,去通過get字元串,反射出屬性或方法
			# BookView的get方法
			handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
		else:
			handler = self.http_method_not_allowed
		# BookView的get方法,加括弧,傳入request
		return hander(request, *args, **kwargs)

APIView執行流程-源碼分析

urls.py

path('books/', views.BookView.as_view()),---》請求來了,執行views.BookView.as_view()()--->現在as_view是APIView的as_view(因為我們把父類從View換成了APIView)

我們點進源碼查看可以發現APIView其實繼承了View

class APIView(View):

往下查找as_view()的代碼

# APIView的as_view方法:view還是原來的view,但是以後再也沒有csrf認證了
	@classmethod
	def as_view(cls, **initkwargs):
		# 調用父類的as_view,父類是Django原生view
		# 把Django原生view的as_view方法中的閉包函數view拿出來了
		view = super().as_view(**initkwargs)
		# csrf_exempt 排除所有csrf的認證
		# 相當於再所有的方法上面加了這個裝飾器
		return csrf_exempt(view)
'從他內部的view我們可以看到他是用派生方法調用父類View中的as_view因此我們說view還是原來的view,但是返回的結果是csrf_exempt(view),回顧裝飾器的知識,我們可以知道雖然把裝飾器寫成了語法糖,但是在運行的時候其實就是把被裝飾的函數名稱傳進來當參數運行,因此這裡就是取消了csrf認證的作用'
# 路由匹配成功,執行的其實就是csrf_exempt(view)(request)--->而這個view就是View的as_view中的閉包函數view---》然後執行self.dispatch--->self是視圖類的對象---》BookView產生的對象---》這時候會執行self.dispatch,根據名稱的查找順序他會查找到APIView的dispatch:
	def dispatch(self, request, *args, **kwargs):
		# 這裡的參數中的request是Django原生request,老的request
		# 把老的request包裝成了新的request,這個是drf提供的Request類的對象
		request = self.initialize_request(request, *args, **kwargs):
		# 到此以後,這個request就是新的了,老的request在request._request這是老的
		
		# 把新的request放到了self對象【BookView的對象】
		self.request = reqeust
		try:
			# 執行了三大認證【認證、頻率、許可權】,使用新的request,之後會將
			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
					# 把新的request傳入了,視圖類的方法中get的request也是新的
			response = handler(request, *atgs, **kwargs)
		except Exception as exc:
			# 在執行3大認證和視圖類中方法的過程中,如果出了異常,都能捕獲到---》全局異常捕獲
			response = self.handle_exception(exc)
		self.response = self.finalize_response(request, response, *args, **kwargs)
		return self.response
		
		

'上方的request調用了initialize_request方法,這個方法的返回結果產生了一個Request生成的對象,它的源碼如下:'
	def initialize_request(self, request, *args, **kwargs):
		parser_context = self.get_parser_context(request)
		return Request(
			reqeust,
			parsers=self.get_parsers(),
			authenticators=self.get_authenticators(),
			negotiator=self.get_content_negotiator(),
			parser_context=parser_context
	)
'接著我們點進這個Request類的源碼,我們會發現老的request變成了_request屬性'
	def __init__(self, request, parsers=None, authenticators=None, negotiator=None, parser_context=None):
		self.request = request
		self.parsers = parsers or ()
		self.authenticators = authenticators or ()
		self.negotiator = negotiator or self._default_negotiator()
		self.parser_context = parser_context
		self._data = Empty
		self._files = Empty
		self._full_data = Empty
		self._content_type = Empty
		self._stream = Empty
		
		
# 總結:APIView的執行流程
1.去除了所以的csrf
2.包裝了新的request,以後在視圖類中用的request Request類的對象,不是原生的了
	-原生的在:新的request._request
3.在執行視圖類的方法之前,執行了三大認證
4.如果三大認證或視圖函數方法執行過程中出了錯,會有異常捕獲---》全局異常捕獲
5.以後視圖類方法中的request都是新的



# 補充:裝飾器的基本原理
def auth()	# 裝飾器
def add()	# 函數

# 使用auth裝飾add函數
@auth	# 本質是	add=auth(add)
def add()

# 以後再使用add,其實就是在使用 auth(add) 的返回結果

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 5 註冊-控制層 5.1 創建響應 狀態碼、狀態碼描述信息、數據。這部分功能封裝到一個類中,將這類作為方法返回值,返回給前端瀏覽器。 package com.cy.store.util; import java.io.Serializable; /** * Json格式的數據進行響應 */ publ ...
  • ThreadLocal 的原理講述 + 基於ThreadLocal實現MVC中的M層的事務控制 每博一文案 生活不是努力了就可以變好的,喜歡做的事情也不是輕易就可以做的。以前總聽別人說, 堅持就好了,努力就好了,都會好的,可是真的做起來壓根就不是這樣。這種時候要怎麼辦? 這種時候還能輕易地相信時間嗎 ...
  • Java的產生和發展 產生與發展歷程 1991年,由Sun公司開發Oak,最初為家用消費電子產品進行編程,是Java前身。 1994年,使用Oak語言編寫了Web瀏覽器 1995年,改名為Java,96年發佈JDK1.1 … 1998年,發佈JDK1.2,從語言發展為平臺 … 2004年,發佈JDK ...
  • 列印輸出的Java對象是一知半解的字元串,那麼這個字元串是怎麼來的?代表什麼?我們如何列印出對象中的數據呢? ...
  • set(可變集合)與frozenset(不可變集合)的區別: set無序排序且不重覆,是可變的,有add(),remove()等方法。既然是可變的,所以它不存在哈希值。基本功能包括關係測試和消除重覆元素. 集合對象還支持union(聯合), intersection(交集), difference( ...
  • MVC 三層架構案例詳細講解 @ 每博一文案 多讀書,書中有,你對生活,困難所解不開的答案 比如:《殺死一隻是更鳥》中提到的 對應我們:我們努力中考,高考,升本,考研,每天都在努力學習,但是某天突然想到萬一沒有考上的話,那現在的努力又有什麼意義呢? 答案:在《殺死一隻是更鳥》里有這樣一段話: > 勇 ...
  • 摘要:本文將從OpenCV和Matplotlib兩個方面介紹如何繪製直方圖,這將為圖像處理像素對比提供有效支撐。 本文分享自華為雲社區《[Python從零到壹] 五十.圖像增強及運算篇之圖像直方圖理論知識和繪製實現》,作者:eastmount。 一.圖像直方圖理論知識 灰度直方圖是灰度級的函數,描述 ...
  • java設計模式【抽象工廠模式】 抽象工廠模式 抽象工廠模式是對簡單工廠模式的一個變種,它允許通過一個統一的介面來創建不同的產品實例,而無需指定具體的子類。在這個模式中,我們只關心產品的抽象介面,而將具體的產品實現留給子類去實現。這樣,我們可以通過創建不同的工廠對象來創建不同的產品實例,而無需關心它 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...