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 02 Python
Python实现约瑟夫环问题的方法
May 03 Python
python3实现抓取网页资源的 N 种方法
May 02 Python
Python中pow()和math.pow()函数用法示例
Feb 11 Python
Python使用pyodbc访问数据库操作方法详解
Jul 05 Python
python opencv判断图像是否为空的实例
Jan 26 Python
Python3.5面向对象程序设计之类的继承和多态详解
Apr 24 Python
基于python实现FTP文件上传与下载操作(ftp&sftp协议)
Apr 01 Python
python使用建议技巧分享(三)
Aug 18 Python
pandas按条件筛选数据的实现
Feb 20 Python
学点简单的Django之第一个Django程序的实现
Feb 24 Python
详解python中[-1]、[:-1]、[::-1]、[n::-1]使用方法
Apr 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
追忆往昔!浅谈收音机的百年发展历史
2021/03/01 无线电
PHP同时连接多个mysql数据库示例代码
2014/03/17 PHP
让codeigniter与swfupload整合的最佳解决方案
2014/06/12 PHP
PHP获取短链接跳转后的真实地址和响应头信息的方法
2014/07/25 PHP
PHP正则表达式替换站点关键字链接后空白的解决方法
2014/09/16 PHP
php图片的二进制转换实现方法
2014/12/15 PHP
JavaScript 比较时间大小的代码
2010/04/24 Javascript
JavaScript小技巧 2.5 则
2010/09/12 Javascript
ToolTips JQEURY插件之简洁小提示框效果
2011/11/19 Javascript
纯javascript实现简单下拉刷新功能
2015/03/13 Javascript
jQuery实现动态添加和删除一个div
2015/08/12 Javascript
浅析AngularJS中的指令
2016/03/20 Javascript
javascript鼠标滑过显示二级菜单特效
2020/11/18 Javascript
JS之相等操作符详解
2016/09/13 Javascript
ES6 Map结构的应用实例分析
2019/06/26 Javascript
JavaScript RegExp 对象用法详解
2019/09/24 Javascript
ES6 async、await的基本使用方法示例
2020/06/06 Javascript
[02:56]DOTA2亚洲邀请赛 VG出场战队巡礼
2015/02/07 DOTA
[43:47]完美世界DOTA2联赛PWL S3 LBZS vs Phoenix 第一场 12.09
2020/12/11 DOTA
Python操作MongoDB详解及实例
2017/05/18 Python
解决pyecharts在jupyter notebook中使用报错问题
2020/04/23 Python
在python中将list分段并保存为array类型的方法
2019/07/15 Python
python读写csv文件的方法
2019/08/13 Python
python中_del_还原数据的方法
2020/12/09 Python
关于前端上传文件全面基础扫盲贴(入门)
2019/08/01 HTML / CSS
哥伦比亚最大的网上商店:Linio哥伦比亚
2016/09/25 全球购物
idealfit英国:世界领先的女性健身用品和运动衣物品牌
2017/11/25 全球购物
英国银首饰公司:e&e Jewellery
2021/02/11 全球购物
电子商务专业毕业生工作推荐信
2013/11/17 职场文书
教师评优事迹材料
2014/01/10 职场文书
《小猪家的桃花树》教学反思
2014/04/11 职场文书
高三励志标语
2014/06/05 职场文书
教师优秀党员事迹材料
2014/08/14 职场文书
公司出差管理制度范本
2015/08/05 职场文书
PHP判断是否是json字符串
2021/04/01 PHP
Python中for后接else的语法使用
2021/05/18 Python