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模块顶层运行的代码引起的一个Bug
Jul 04 Python
使用相同的Apache实例来运行Django和Media文件
Jul 22 Python
Python基于socket实现简单的即时通讯功能示例
Jan 16 Python
Python 数据库操作 SQLAlchemy的示例代码
Feb 18 Python
Python3.6中Twisted模块安装的问题与解决
Apr 15 Python
Python从函数参数类型引出元组实例分析
May 28 Python
Python OpenCV视频截取并保存实现代码
Nov 30 Python
python 解决tqdm模块不能单行显示的问题
Feb 19 Python
DjangoWeb使用Datatable进行后端分页的实现
May 18 Python
详解如何在PyCharm控制台中输出彩色文字和背景
Aug 17 Python
python脚本框架webpy的url映射详解
Nov 20 Python
yolov5返回坐标的方法实例
Mar 17 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读取文件内容后清空文件示例代码
2014/03/18 PHP
php中实现可以返回多个值的函数实例
2015/03/21 PHP
php实现的递归提成方案实例
2015/11/14 PHP
Laravel接收前端ajax传来的数据的实例代码
2017/07/20 PHP
浅谈PHP中pack、unpack的详细用法
2018/03/12 PHP
Laravel 简单实现Ajax滚动加载示例
2019/10/22 PHP
IE中jscript/javascript的条件编译
2006/09/07 Javascript
javascript学习笔记(十二) RegExp类型介绍
2012/06/20 Javascript
JS继承--原型链继承和类式继承
2013/04/08 Javascript
简略说明Javascript中的= =(等于)与= = =(全等于)区别
2013/04/16 Javascript
js带前后翻页的图片切换效果代码分享
2015/09/08 Javascript
实现JavaScript的组成----BOM和DOM详解
2016/05/18 Javascript
实例解析jQuery中proxy()函数的用法
2016/05/24 Javascript
React Native实现简单的登录功能(推荐)
2016/09/19 Javascript
JS实现根据用户输入分钟进行倒计时功能
2016/11/14 Javascript
Bootstrap基本组件学习笔记之导航(10)
2016/12/07 Javascript
vue2.0实现导航菜单切换效果
2017/05/08 Javascript
vuejs 单文件组件.vue 文件的使用
2017/07/28 Javascript
javascript中神奇的 Date对象小结
2017/10/12 Javascript
微信小程序修改swiper默认指示器样式的实例代码
2018/07/18 Javascript
es6函数中的作用域实例分析
2020/04/18 Javascript
Webpack5正式发布,有哪些新特性
2020/10/12 Javascript
[01:33:07]VGJ.T vs Newbee Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
python中getattr函数使用方法 getattr实现工厂模式
2014/01/20 Python
详谈python在windows中的文件路径问题
2018/04/28 Python
python list是否包含另一个list所有元素的实例
2018/05/04 Python
Python DataFrame设置/更改列表字段/元素类型的方法
2018/06/09 Python
Python实现随机漫步功能
2018/07/09 Python
python3+django2开发一个简单的人员管理系统过程详解
2019/07/23 Python
Python中sys模块功能与用法实例详解
2020/02/26 Python
Python实现UDP程序通信过程图解
2020/05/15 Python
加拿大户外探险购物网站:SAIL
2020/06/27 全球购物
教育实习指导教师评语
2014/12/31 职场文书
《金钱的魔力》教学反思
2016/02/20 职场文书
使用python向MongoDB插入时间字段的操作
2021/05/18 Python
golang为什么要统一错误处理
2022/04/03 Golang