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生成器的使用方法
Nov 21 Python
Python数据类型中的“冒号“[::]——分片与步长操作示例
Jan 24 Python
python检索特定内容的文本文件实例
Jun 05 Python
详解pandas安装若干异常及解决方案总结
Jan 10 Python
python调用matlab的m自定义函数方法
Feb 18 Python
python Django 创建应用过程图示详解
Jul 29 Python
pytorch中的embedding词向量的使用方法
Aug 18 Python
Python 静态方法和类方法实例分析
Nov 21 Python
Python3 实现减少可调用对象的参数个数
Dec 20 Python
基于Pygame实现简单的贪吃蛇游戏
Dec 06 Python
Python闭包的定义和使用方法
Apr 11 Python
Python之matplotlib绘制饼图
Apr 13 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
一个程序下载的管理程序(三)
2006/10/09 PHP
MySQL数据库转移,access,sql server 转 MySQL 的图文教程
2007/09/02 PHP
解析php函数method_exists()与is_callable()的区别
2013/06/21 PHP
是 WordPress 让 PHP 更流行了 而不是框架
2016/02/03 PHP
CI框架扩展系统核心类的方法分析
2016/05/23 PHP
jquery实现控制表格行高亮实例
2013/06/05 Javascript
原生javascript获取元素样式
2014/12/31 Javascript
浅谈jQuery构造函数分析
2015/05/11 Javascript
Jquery UI实现一次拖拽多个选中的元素操作
2020/12/01 Javascript
Javascript oop设计模式 面向对象编程简单实例介绍
2016/12/13 Javascript
nodejs根据ip数组在百度地图中进行定位
2017/03/06 NodeJs
vue.js根据代码运行环境选择baseurl的方法
2018/02/28 Javascript
vue router 配置路由的方法
2018/07/26 Javascript
利用js canvas实现五子棋游戏
2020/10/11 Javascript
在vue中给后台接口传的值为数组的格式代码
2020/11/12 Javascript
微信小程序实现自定义底部导航
2020/11/18 Javascript
Python中的类学习笔记
2014/09/23 Python
Mac下Supervisor进程监控管理工具的安装与配置
2014/12/16 Python
python实现连接mongodb的方法
2015/05/08 Python
关于Python如何避免循环导入问题详解
2017/09/14 Python
Python实现的读取电脑硬件信息功能示例
2018/05/30 Python
利用Python如何批量更新服务器文件
2018/07/29 Python
python如何获取当前文件夹下所有文件名详解
2019/01/25 Python
python3连接kafka模块pykafka生产者简单封装代码
2019/12/23 Python
Python Tensor FLow简单使用方法实例详解
2020/01/14 Python
美国女性服饰销售网站:Nasty Gal(坏女孩)
2016/07/26 全球购物
新加坡时尚网上购物:Zalora新加坡
2016/07/26 全球购物
美国环保婴儿用品公司:The Honest Company
2017/11/23 全球购物
数据库连接池的工作原理
2012/09/26 面试题
物流专业大学的自我评价
2014/01/11 职场文书
护士辞职信模板
2014/01/20 职场文书
工作违纪检讨书
2014/02/17 职场文书
中秋节主持词
2014/04/02 职场文书
酒店管理专业毕业生自我鉴定
2014/09/29 职场文书
中标通知书格式
2015/04/17 职场文书
Python中使用tkFileDialog实现文件选择、保存和路径选择
2022/05/20 Python