django-rest-framework解析請求參數(shù)過程詳解
前言
我們在django-rest-framework 自定義swagger 文章中編寫了接口, 調(diào)通了接口文檔. 接口文檔可以直接填寫參數(shù)進行請求, 接下來的問題是如何接受參數(shù), 由于請求方式與參數(shù)序列化形式的不同, 接收參數(shù)的方式也有不同.
前提條件
服務(wù)端我們使用django-rest-framework編寫接口.
class ReturnJson(APIView):
coreapi_fields=(
DocParam("token"),
)
def get(self, request, *args, **kwargs):
return JsonResponse("Hello world!!!!!!!!++++++中文測試")
這是一個簡單接口, ReturnJson繼承自APIView
而APIView 來自from rest_framework.views import APIView
以下 def get, def post等等的前提條件都是接口類繼承自APIView.
當然還可以繼承自其它的類例如.
from rest_framework import viewsets, generics
class ReturnJson(generics.ListCreateAPIView) class ReturnJson(viewsets.ModelViewSet)
他們的用法各有特點, 詳情查看
- http://www.django-rest-framework.org/api-guide/viewsets/
- http://www.django-rest-framework.org/api-guide/generic-views/
- http://www.django-rest-framework.org/api-guide/views/
django-rest-framework如何編寫一個接口.
class ReturnJson(APIView):
coreapi_fields=(
DocParam("token"),
)
def get(self, request, *args, **kwargs):
return JsonResponse("Hello world!!!!!!!!++++++中文測試")
def post(self, request, *args, **kwargs):
return JsonResponse(data={})
def put(self, request, *args, **kwargs):
return JsonResponse(data={})
對一個APIView的子類, 重寫get, post, put等方法就相當于解析這個路徑的get, post, put請求,
請求對象就是request對象, http header body 的內(nèi)容都被包含在request對象中.
request對象的類來自from rest_framework.request import Request
判斷對象是否是某個類實例化而來
from rest_framework.request import Request if isinstance(request, Request)
下面分別分析不同情況的參數(shù)位置和類型, 最終寫出一個方法能夠?qū)⑷魏晤愋偷恼埱髤?shù)統(tǒng)一轉(zhuǎn)換為dict方便之后的邏輯編寫.
GET
get請求中參數(shù)都會以http://xxx.com/api/getjson?param1=asdf¶m2=123
這樣的形式拼接在url后面.
在request對象中
- request.query_params 中可以獲取?param1=32¶m2=23形式的參數(shù).
- request.query_params 返回的數(shù)據(jù)類型為QueryDict
- QueryDict轉(zhuǎn)為普通python字典. query_params.dict()即可.
POST
post 請求參數(shù)都在請求體中, 但是其實你的url可以寫成get的形式, 最終結(jié)果, 參數(shù)會有兩部分組成, 一部分在url中, 一部分在http body 中, 但是非常不建議這樣做.
接下來的代碼編寫也不會考慮這樣的情況, post 僅考慮所有參數(shù)都在http body 中的情況.
| 提交類型 | 參數(shù)位置 | 參數(shù)類型 |
|---|---|---|
| form-data提交, | 參數(shù)在data中, | 類型為QueryDict |
| application/json提交 | 參數(shù)在data中 | 類型為dict |
| (swagger)使用接口文檔提交, 由于使用curl提交, 雖然是post 但是參數(shù)依然被類似get的形式拼接到了url之后, | 此時 參數(shù)在query_params 中 | 類型為 QueryDict |
| x-www-form-urlencoded | 參數(shù)在data中 | 類型為 QueryDict |
PUT
| 提交類型 | 參數(shù)位置 | 參數(shù)類型 |
|---|---|---|
| form-data | request.data | QueryDict |
| application/json | request.data | dict |
| x-www-form-urlencoded | request.data | QueryDict |
| (swagger) | request.data | dict |
PATCH
| 提交類型 | 參數(shù)位置 | 參數(shù)類型 |
|---|---|---|
| form-data | request.data | QueryDict |
| application/json | request.data | dict |
| x-www-form-urlencoded | request.data | QueryDict |
| (swagger) | request.data | dict |
DELETE
| 提交類型 | 參數(shù)位置 | 參數(shù)類型 |
|---|---|---|
| form-data | request.data | QueryDict |
| application/json | request.data | dict |
| x-www-form-urlencoded | request.data | QueryDict |
| (swagger) | request.query_params | QueryDict |
| iOS端提交和get情況一樣 | request.query_params | QueryDict |
編寫參數(shù)統(tǒng)一處理的方法
總結(jié)一下, 當url有?param=1¶m=2這樣的參數(shù)時忽略body中的參數(shù), 例如get,delete提交,如果query_params有內(nèi)容, 則忽略body內(nèi)容. 將QueryDict轉(zhuǎn)為dict返回, 再判斷request.data中是否有內(nèi)容, 類型如何.
from django.http import QueryDict
from rest_framework.request import Request
def get_parameter_dic(request, *args, **kwargs):
if isinstance(request, Request) == False:
return {}
query_params = request.query_params
if isinstance(query_params, QueryDict):
query_params = query_params.dict()
result_data = request.data
if isinstance(result_data, QueryDict):
result_data = result_data.dict()
if query_params != {}:
return query_params
else:
return result_data
使用方法
class ReturnJson(APIView):
coreapi_fields=(
DocParam("token"),
)
def get(self, request, *args, **kwargs):
params=get_parameter_dic(request)
return JsonResponse(data=params)
def post(self, request, *args, **kwargs):
params=get_parameter_dic(request)
return JsonResponse(data=params)
def put(self, request, *args, **kwargs):
params=get_parameter_dic(request)
return JsonResponse(data=params)
最后的效果

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python的Socket編程過程中實現(xiàn)UDP端口復(fù)用的實例分享
這篇文章主要介紹了Python的Socket編程過程中實現(xiàn)UDP端口復(fù)用的實例分享,文中作者用到了Python的twisted異步框架,需要的朋友可以參考下2016-03-03
Python中的Socket 與 ScoketServer 通信及遇到問題解決方法
Socket有一個緩沖區(qū),緩沖區(qū)是一個流,先進先出,發(fā)送和取出的可自定義大小的,如果取出的數(shù)據(jù)未取完緩沖區(qū),則可能存在數(shù)據(jù)怠慢。本文通過實例代碼給大家介紹Python中的Socket 與 ScoketServer 通信及遇到問題解決方法 ,需要的朋友參考下吧2019-04-04
Python3與redis交互,保存的是字符串,取出來是bytes類型問題
這篇文章主要介紹了Python3與redis交互,保存的是字符串,取出來是bytes類型問題,具有很好的參考價值,希望對大家有所幫助,2023-09-09
基于文件路徑中/?\?//?\\的用法以及絕對相對路徑的問題
這篇文章主要介紹了基于文件路徑中/?\?//?\\的用法以及絕對相對路徑的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02

