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脚本将文字转换为图片的实例分享
Aug 29 Python
Python正则表达式教程之二:捕获篇
Mar 02 Python
Python 的类、继承和多态详解
Jul 16 Python
深入理解Django的自定义过滤器
Oct 17 Python
Python实现聊天机器人的示例代码
Jul 09 Python
pyqt实现.ui文件批量转换为对应.py文件脚本
Jun 19 Python
Python搭建代理IP池实现获取IP的方法
Oct 27 Python
tensorflow之自定义神经网络层实例
Feb 07 Python
python raise的基本使用
Sep 10 Python
利用django创建一个简易的博客网站的示例
Sep 29 Python
Python pip 常用命令汇总
Oct 19 Python
python 实现图片特效处理
Apr 03 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
discuz7 phpMysql操作类
2009/06/21 PHP
php中读写文件与读写数据库的效率比较分享
2013/10/19 PHP
laravel 5 实现模板主题功能
2015/03/02 PHP
YII2框架中使用yii.js实现的post请求
2017/04/09 PHP
javascript针对DOM的应用实例(一)
2012/04/15 Javascript
js替代copy(示例代码)
2013/11/27 Javascript
javascript简单实现表格行间隔显示颜色并高亮显示
2013/11/29 Javascript
Node.js中对通用模块的封装方法
2014/06/06 Javascript
我的Node.js学习之路(三)--node.js作用、回调、同步和异步代码 以及事件循环
2014/07/06 Javascript
轻松学习Javascript闭包函数
2015/12/15 Javascript
AngularJS基础 ng-model 指令详解及示例代码
2016/08/02 Javascript
微信小程序实战之顶部导航栏(选项卡)(1)
2020/06/19 Javascript
在node中如何使用 ES6
2017/04/22 Javascript
值得分享和收藏的xmlplus组件学习教程
2017/05/05 Javascript
jQuery Validate 无法验证 chosen-select元素的解决方法
2017/05/17 jQuery
十大 Node.js 的 Web 框架(快速提升工作效率)
2017/06/30 Javascript
JS中用EL表达式获取上下文参数值的方法
2018/03/28 Javascript
JavaScript中七种流行的开源机器学习框架
2018/10/11 Javascript
微信小程序实现用table显示数据库反馈的多条数据功能示例
2019/05/07 Javascript
layui type2 通过url给iframe子页面传值的例子
2019/09/06 Javascript
Python正则捕获操作示例
2017/08/19 Python
快速解决PyCharm无法引用matplotlib的问题
2018/05/24 Python
python 循环读取txt文档 并转换成csv的方法
2018/10/26 Python
用python解压分析jar包实例
2020/01/16 Python
如何基于windows实现python定时爬虫
2020/05/01 Python
Python+Dlib+Opencv实现人脸采集并表情判别功能的代码
2020/07/01 Python
女子锻炼服装和瑜伽服装:Splits59
2019/03/04 全球购物
Ray-Ban雷朋奥地利官网:全球领先的太阳眼镜品牌
2020/10/12 全球购物
介绍下Java的输入输出流
2014/01/22 面试题
医学专业毕业生推荐信
2013/11/14 职场文书
教师通用专业自荐书范文
2014/02/11 职场文书
2015年青年志愿者工作总结
2015/05/20 职场文书
2015年电教工作总结
2015/05/26 职场文书
劳务派遣管理制度(样本)
2019/08/23 职场文书
Python基础知识之变量的详解
2021/04/14 Python
如何在CSS中绘制曲线图形及展示动画
2021/05/24 HTML / CSS