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 相关文章推荐
python实现simhash算法实例
Apr 25 Python
Python中变量交换的例子
Aug 25 Python
Python批量更改文件名的实现方法
Oct 29 Python
利用python 更新ssh 远程代码 操作远程服务器的实现代码
Feb 08 Python
python中的二维列表实例详解
Jun 19 Python
Python基于SMTP协议实现发送邮件功能详解
Aug 14 Python
Django如何开发简单的查询接口详解
May 17 Python
python使用pygame实现笑脸乒乓球弹珠球游戏
Nov 25 Python
python实现logistic分类算法代码
Feb 28 Python
基于python实现检索标记敏感词并输出
May 07 Python
史上最详细的Python打包成exe文件教程
Jan 17 Python
python爬取豆瓣电影排行榜(requests)的示例代码
Feb 18 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+MYSQL开发工具及资源收藏
2007/01/02 PHP
php中变量及部分适用方法
2008/03/27 PHP
PHP无限分类(树形类)的深入分析
2013/06/02 PHP
php日历制作代码分享
2014/01/20 PHP
C/S和B/S两种架构区别与优缺点分析
2014/10/23 PHP
PHP常用设计模式之委托设计模式
2016/02/13 PHP
php读取qqwry.dat ip地址定位文件的类实例代码
2016/11/15 PHP
PHP长网址与短网址的实现方法
2017/10/13 PHP
php实现微信支付之退款功能
2018/05/30 PHP
javascript AOP 实现ajax回调函数使用比较方便
2010/11/20 Javascript
js使用eval解析json实例与注意事项分享
2014/01/18 Javascript
jQuery使用deferreds串行多个ajax请求
2016/08/22 Javascript
jQuery模拟实现的select点击选择效果【附demo源码下载】
2016/11/09 Javascript
bootstrap table实例详解
2017/01/06 Javascript
详解vue2.0 使用动态组件实现 Tab 标签页切换效果(vue-cli)
2017/08/30 Javascript
vue组件发布到npm简单步骤
2017/11/30 Javascript
基于wordpress的ajax写法详解
2018/01/02 Javascript
vue 自定义指令自动获取文本框焦点的方法
2018/08/25 Javascript
vue-cli 打包使用history模式的后端配置实例
2018/09/20 Javascript
在类Unix系统上开始Python3编程入门
2015/08/20 Python
详解python中xlrd包的安装与处理Excel表格
2016/12/16 Python
Python读写及备份oracle数据库操作示例
2018/05/17 Python
Python反射和内置方法重写操作详解
2018/08/27 Python
django的ORM操作 删除和编辑实现详解
2019/07/24 Python
python plotly画柱状图代码实例
2019/12/13 Python
python线程池 ThreadPoolExecutor 的用法示例
2020/10/10 Python
django中ImageField的使用详解
2020/12/21 Python
Mytheresa英国官网:拥有160多个奢侈品品牌
2016/10/09 全球购物
Clearly新西兰:购买眼镜、太阳镜和隐形眼镜
2018/04/26 全球购物
接口可以包含哪些成员
2012/09/30 面试题
C#里面如何倒序排列一个数组的元素?
2013/06/21 面试题
优秀求职自荐信怎样写
2013/12/18 职场文书
大二学生学年自我鉴定
2014/09/12 职场文书
群众路线教育实践活动心得体会(四风)
2014/11/03 职场文书
公司回复函格式
2015/07/14 职场文书
生日宴会家属答谢词
2015/09/29 职场文书