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调用新浪微博API项目实践
Jul 28 Python
在Python中用has_key()方法查找键是否存在的教程
May 21 Python
python数据结构之图深度优先和广度优先实例详解
Jul 08 Python
使用Flask集成bootstrap的方法
Jul 24 Python
Python django使用多进程连接mysql错误的解决方法
Oct 08 Python
python石头剪刀布小游戏(三局两胜制)
Jan 20 Python
浅谈python标准库--functools.partial
Mar 13 Python
Python读写文件基础知识点
Jun 10 Python
Pytorch中膨胀卷积的用法详解
Jan 07 Python
将自己的数据集制作成TFRecord格式教程
Feb 17 Python
Python urllib request模块发送请求实现过程解析
Dec 10 Python
2021年值得向Python开发者推荐的VS Code扩展插件
Jan 25 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
实用函数4
2007/11/08 PHP
利用PHP实现短域名互转
2013/07/05 PHP
必须收藏的23个php实用代码片段
2016/02/02 PHP
Linux环境下php实现给网站截图的方法
2016/05/03 PHP
PHP面向对象之领域模型+数据映射器实例(分析)
2017/06/21 PHP
一种JavaScript的设计模式
2006/11/22 Javascript
js截取中英文字符串、标点符号无乱码示例解读
2014/04/17 Javascript
JavaScript中的Math 使用介绍
2014/04/21 Javascript
ExtJS4利根据登录后不同的角色分配不同的树形菜单
2014/05/02 Javascript
JavaScript使用循环和分割来替换和删除元素实例
2014/10/13 Javascript
Google 地图API Map()构造器详解
2016/08/06 Javascript
javascript宿主对象之window.navigator详解
2016/09/07 Javascript
JS获取IE版本号与HTML设置IE文档模式的方法
2016/10/09 Javascript
Vue.js使用v-show和v-if的注意事项
2016/12/13 Javascript
jQuery按需加载轮播图(web前端性能优化)
2017/02/17 Javascript
原生js编写2048小游戏
2017/03/17 Javascript
js使用html2canvas实现屏幕截取的示例代码
2017/08/28 Javascript
Vue中render方法的使用详解
2018/01/26 Javascript
Nodejs实现用户注册功能
2019/04/14 NodeJs
vue+element实现图片上传及裁剪功能
2020/06/29 Javascript
[08:54]《一刀刀一天》之DOTA全时刻18:十九支奔赴西雅图队伍全部出炉
2014/06/04 DOTA
[00:57]英雄,你的补给到了!
2020/11/13 DOTA
Python 文件处理注意事项总结
2017/04/10 Python
基于Python 装饰器装饰类中的方法实例
2018/04/21 Python
Python使用progressbar模块实现的显示进度条功能
2018/05/31 Python
解决python gdal投影坐标系转换的问题
2020/01/17 Python
宝塔面板成功部署Django项目流程(图文)
2020/06/22 Python
python 通过pip freeze、dowload打离线包及自动安装的过程详解(适用于保密的离线环境
2020/12/14 Python
你在项目中用到了xml技术的哪些方面?如何实现的?
2014/01/26 面试题
求职简历自荐信范文
2013/10/21 职场文书
个人评价范文分享
2014/01/11 职场文书
房地产财务部员工岗位职责
2014/03/12 职场文书
道德之星事迹材料
2014/05/03 职场文书
本科毕业生应聘求职信
2014/07/06 职场文书
赵氏孤儿观后感
2015/06/09 职场文书
银行工作心得体会范文
2016/01/23 职场文书