django-rest-framework解析请求参数过程详解


Posted in Python onJuly 18, 2019

前言

我们在django-rest-framework 自定义swagger 文章中编写了接口, 调通了接口文档. 接口文档可以直接填写参数进行请求, 接下来的问题是如何接受参数, 由于请求方式与参数序列化形式的不同, 接收参数的方式也有不同.

前提条件

服务端我们使用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 的内容都被包含在request对象中.
request对象的类来自from rest_framework.request import Request

判断对象是否是某个类实例化而来

from rest_framework.request import Request
if isinstance(request, Request)

下面分别分析不同情况的参数位置和类型, 最终写出一个方法能够将任何类型的请求参数统一转换为dict方便之后的逻辑编写.

GET

get请求中参数都会以http://xxx.com/api/getjson?param1=asdf¶m2=123
这样的形式拼接在url后面.

在request对象中

  • request.query_params 中可以获取?param1=32¶m2=23形式的参数.
  • request.query_params 返回的数据类型为QueryDict
  • QueryDict转为普通python字典. query_params.dict()即可.

POST

post 请求参数都在请求体中, 但是其实你的url可以写成get的形式, 最终结果, 参数会有两部分组成, 一部分在url中, 一部分在http body 中, 但是非常不建议这样做.

接下来的代码编写也不会考虑这样的情况, post 仅考虑所有参数都在http body 中的情况.

提交类型 参数位置 参数类型
form-data提交, 参数在data中, 类型为QueryDict
application/json提交 参数在data中 类型为dict
(swagger)使用接口文档提交, 由于使用curl提交, 虽然是post 但是参数依然被类似get的形式拼接到了url之后, 此时 参数在query_params 中 类型为 QueryDict
x-www-form-urlencoded 参数在data中 类型为 QueryDict

PUT

提交类型 参数位置 参数类型
form-data request.data QueryDict
application/json request.data dict
x-www-form-urlencoded request.data QueryDict
(swagger) request.data dict

PATCH

提交类型 参数位置 参数类型
form-data request.data QueryDict
application/json request.data dict
x-www-form-urlencoded request.data QueryDict
(swagger) request.data dict

DELETE

提交类型 参数位置 参数类型
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

编写参数统一处理的方法

总结一下, 当url有?param=1¶m=2这样的参数时忽略body中的参数, 例如get,delete提交,如果query_params有内容, 则忽略body内容. 将QueryDict转为dict返回, 再判断request.data中是否有内容, 类型如何.

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)

最后的效果

django-rest-framework解析请求参数过程详解

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
使用grappelli为django admin后台添加模板
Nov 18 Python
举例讲解Python中的身份运算符的使用方法
Oct 13 Python
对Python协程之异步同步的区别详解
Feb 19 Python
利用Pandas和Numpy按时间戳将数据以Groupby方式分组
Jul 22 Python
Python:二维列表下标互换方式(矩阵转置)
Dec 02 Python
pytorch中tensor.expand()和tensor.expand_as()函数详解
Dec 27 Python
浅谈ROC曲线的最佳阈值如何选取
Feb 28 Python
Python reversed函数及使用方法解析
Mar 17 Python
利用matplotlib为图片上添加触发事件进行交互
Apr 23 Python
python的reverse函数翻转结果为None的问题
May 11 Python
详解Python中的Lock和Rlock
Jan 26 Python
Django框架模板用法详解
Jun 10 Python
python Django中models进行模糊查询的示例
Jul 18 #Python
django-rest-framework 自定义swagger过程详解
Jul 18 #Python
django框架使用方法详解
Jul 18 #Python
Ubuntu+python将nii图像保存成png格式
Jul 18 #Python
python实现批量nii文件转换为png图像
Jul 18 #Python
django 捕获异常和日志系统过程详解
Jul 18 #Python
Django实现发送邮件功能
Jul 18 #Python
You might like
详谈PHP编码转换问题
2015/07/28 PHP
[原创]php常用字符串输出方法分析(echo,print,printf及sprintf)
2016/07/09 PHP
PHP面向对象程序设计之对象生成方法详解
2016/12/02 PHP
PHP mysqli事务操作常用方法分析
2017/07/22 PHP
PHP+Redis事务解决高并发下商品超卖问题(推荐)
2020/08/03 PHP
javascript 文档的编码问题解决
2009/03/01 Javascript
jQuery 选择器理解
2010/03/16 Javascript
JS限制上传图片大小不使用控件在本地实现
2012/12/19 Javascript
常用的JavaScript验证正则表达式汇总
2013/11/26 Javascript
node.js中的fs.futimesSync方法使用说明
2014/12/17 Javascript
js自制图片放大镜功能
2017/01/24 Javascript
JavaScript省市级联下拉菜单实例
2017/02/14 Javascript
JavaScript错误处理和堆栈追踪详解
2017/04/18 Javascript
浅谈node的事件机制
2017/10/09 Javascript
angular 表单验证器验证的同时限制输入的实现
2019/04/11 Javascript
vue实现计步器功能
2019/11/01 Javascript
js实现百度淘宝搜索功能
2020/02/17 Javascript
JS数组降维的实现Array.prototype.concat.apply([], arr)
2020/04/28 Javascript
JavaScript实现网页下拉菜单效果
2020/11/20 Javascript
python爬虫入门教程--正则表达式完全指南(五)
2017/05/25 Python
Python实现树的先序、中序、后序排序算法示例
2017/06/23 Python
python os.listdir按文件存取时间顺序列出目录的实例
2018/10/21 Python
python实现维吉尼亚算法
2019/03/20 Python
在python中将list分段并保存为array类型的方法
2019/07/15 Python
PyCharm使用之配置SSH Interpreter的方法步骤
2019/12/26 Python
Python Tensor FLow简单使用方法实例详解
2020/01/14 Python
python GUI库图形界面开发之PyQt5复选框控件QCheckBox详细使用方法与实例
2020/02/28 Python
Python如何实现的二分查找算法
2020/05/27 Python
python转化excel数字日期为标准日期操作
2020/07/14 Python
前端隐藏出边界内容的实现方法
2016/04/14 HTML / CSS
HTML5的标签的代码的简单介绍 HTML5标签的简介
2012/05/28 HTML / CSS
数控技术应届生求职信
2013/11/13 职场文书
浙江省杭州市平均工资标准是多少?
2019/07/09 职场文书
复制别人的成功真的会成功吗?
2019/10/17 职场文书
使用CSS实现黑白格背景效果
2022/06/01 HTML / CSS
详解Go语言中配置文件使用与日志配置
2022/06/01 Golang