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 不关闭控制台的实现方法
Oct 23 Python
python pdb调试方法分享
Jan 21 Python
跟老齐学Python之有容乃大的list(1)
Sep 14 Python
使用Python实现一个简单的项目监控
Mar 31 Python
Python的消息队列包SnakeMQ使用初探
Jun 29 Python
用pycharm开发django项目示例代码
Jun 13 Python
TensorFlow实现checkpoint文件转换为pb文件
Feb 10 Python
Python实现遗传算法(二进制编码)求函数最优值方式
Feb 11 Python
python中if及if-else如何使用
Jun 02 Python
Django利用elasticsearch(搜索引擎)实现搜索功能
Nov 26 Python
python Protobuf定义消息类型知识点讲解
Mar 02 Python
判断Python中的Nonetype类型
May 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
php4的session功能评述(三)
2006/10/09 PHP
PHP利用str_replace防注入的方法
2013/11/10 PHP
php制作的简单验证码识别代码
2016/01/26 PHP
PHP判断数组是否为空的常用方法(五种方法)
2017/02/08 PHP
几行代码轻松实现PHP文件打包下载zip
2017/03/01 PHP
Js 刷新框架页的代码
2010/04/13 Javascript
一些常用且实用的原生JavaScript函数
2010/09/08 Javascript
JS TextArea字符串长度限制代码集合
2012/10/31 Javascript
jQuery实现鼠标经过图片预览大图效果
2014/04/10 Javascript
JavaScript验证Email(3种方法)
2015/09/21 Javascript
基于vue的短信验证码倒计时demo
2017/09/13 Javascript
浅谈React Native Flexbox布局(小结)
2018/01/08 Javascript
解决vue 界面在苹果手机上滑动点击事件等卡顿问题
2018/11/27 Javascript
vue-cli 目录结构详细讲解总结
2019/01/15 Javascript
如何利用JavaScript编写更好的条件语句详解
2020/08/10 Javascript
python中map()函数的使用方法示例
2017/09/29 Python
让Python更加充分的使用Sqlite3
2017/12/11 Python
解决PyCharm的Python.exe已经停止工作的问题
2018/11/29 Python
Python中使用__new__实现单例模式并解析
2019/06/25 Python
python实现KNN分类算法
2019/10/16 Python
Python高级特性——详解多维数组切片(Slice)
2019/11/26 Python
Python标准库:内置函数max(iterable, *[, key, default])说明
2020/04/25 Python
详解Html5中video标签那些属性和方法
2019/07/01 HTML / CSS
如何查看浏览器对html5的支持情况
2020/12/15 HTML / CSS
美国女性卫生用品公司:Thinx
2017/06/30 全球购物
中国一家综合的外贸B2C电子商务网站:DealeXtreme(DX)
2020/03/10 全球购物
Wiggle澳大利亚:自行车、跑步、游泳商店
2020/11/07 全球购物
运动鞋、街头服装、手表和手袋的实时市场:StockX
2020/11/25 全球购物
组织关系转移介绍信
2014/01/16 职场文书
大学生社会实践自我鉴定
2014/03/24 职场文书
工业自动化专业自荐信范文
2014/04/10 职场文书
服务承诺书怎么写
2014/05/24 职场文书
期末考试复习计划
2015/01/19 职场文书
2016春节家属慰问信
2015/03/25 职场文书
导游词之无锡丝业博物馆
2019/11/12 职场文书
中国十大神话动漫电影排行榜 哪吒登顶 白蛇缘起排第七
2022/03/21 国漫