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多线程学习资料
Dec 19 Python
python中的__slots__使用示例
Feb 26 Python
Python 爬虫学习笔记之正则表达式
Sep 21 Python
Python基于list的append和pop方法实现堆栈与队列功能示例
Jul 24 Python
python调用staf自动化框架的方法
Dec 26 Python
Python和Go语言的区别总结
Feb 20 Python
python通过nmap扫描在线设备并尝试AAA登录(实例代码)
Dec 30 Python
TensorFlow命名空间和TensorBoard图节点实例
Jan 23 Python
pymysql 插入数据 转义处理方式
Mar 02 Python
python模拟实现分发扑克牌
Apr 22 Python
python多进程下的生产者和消费者模型
May 07 Python
keras实现多GPU或指定GPU的使用介绍
Jun 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+html5使用FormData对象提交表单及上传图片的方法
2015/02/11 PHP
解决Laravel blade模板转义html标签的问题
2019/09/03 PHP
laravel批量生成假数据的方法
2019/10/09 PHP
基于jQuery的弹出警告对话框美化插件(警告,确认和提示)
2010/06/10 Javascript
jquery入门—数据删除与隔行变色以及图片预览
2013/01/07 Javascript
setTimeout函数兼容各主流浏览器运行执行效果实例
2013/06/13 Javascript
JS小游戏之极速快跑源码详解
2014/09/25 Javascript
JQuery选择器绑定事件及修改内容的方法
2015/01/23 Javascript
URL中“#” “?” &“”号的作用浅析
2017/02/04 Javascript
Angular中$broadcast和$emit的使用方法详解
2017/05/22 Javascript
详解Angular2响应式表单
2017/06/14 Javascript
ES6中字符串string常用的新增方法小结
2017/11/07 Javascript
JS实现小球的弹性碰撞效果
2017/11/11 Javascript
ionic3实战教程之随机布局瀑布流的实现方法
2017/12/28 Javascript
AngularJS实现的锚点楼层跳转功能示例
2018/01/02 Javascript
解决Vue2.x父组件与子组件之间的双向绑定问题
2018/03/06 Javascript
JavaScript fetch接口案例解析
2018/08/30 Javascript
小白教程|一小时上手最流行的前端框架vue(推荐)
2019/04/10 Javascript
vue cli3 调用百度翻译API翻译页面的实现示例
2019/09/13 Javascript
Vue多选列表组件深入详解
2021/03/02 Vue.js
[36:13]Mineski vs iG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python正则表达式匹配HTML页面编码
2015/04/08 Python
python 中的list和array的不同之处及转换问题
2018/03/13 Python
Python OS模块实例详解
2019/04/15 Python
Python3 实现减少可调用对象的参数个数
2019/12/20 Python
使用javascript和HTML5 Canvas画的四渐变色播放按钮效果
2014/04/10 HTML / CSS
Brasty波兰:香水、化妆品、手表网上商店
2019/04/15 全球购物
哥伦比亚加拿大官网:Columbia Sportswear Canada
2020/09/07 全球购物
给校长的建议书
2014/03/12 职场文书
公职人员索取回扣检举信
2014/04/04 职场文书
建筑工地质量标语
2014/06/12 职场文书
国庆促销活动总结
2014/08/29 职场文书
2015年司机工作总结
2015/04/23 职场文书
爱国主义教育基地观后感
2015/06/18 职场文书
三八红旗手先进事迹材料(2016推荐版)
2016/02/25 职场文书
80后创业总结的9条职场用人思想,记得收藏
2019/08/13 职场文书