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 Mysql自动备份脚本
Jul 14 Python
python图像处理之镜像实现方法
May 30 Python
Python批量创建迅雷任务及创建多个文件
Feb 13 Python
在Python程序和Flask框架中使用SQLAlchemy的教程
Jun 06 Python
用Pygal绘制直方图代码示例
Dec 07 Python
Python网络编程基于多线程实现多用户全双工聊天功能示例
Apr 10 Python
Selenium鼠标与键盘事件常用操作方法示例
Aug 13 Python
Django框架组成结构、基本概念与文件功能分析
Jul 30 Python
浅谈Python中(&,|)和(and,or)之间的区别
Aug 07 Python
Pycharm 安装 idea VIM插件的图文教程详解
Feb 21 Python
python 监控服务器是否有人远程登录(详细思路+代码)
Dec 18 Python
Python 装饰器(decorator)常用的创建方式及解析
Apr 24 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递归列出所有文件和目录的代码
2008/09/10 PHP
php中根据某年第几天计算出日期年月日的代码
2011/02/24 PHP
PHP将两个关联数组合并函数提高函数效率
2014/03/18 PHP
php操作路径的经典方法(必看篇)
2016/10/04 PHP
PHP实现简单计算器小程序
2020/08/28 PHP
laravel框架数据库操作、查询构建器、Eloquent ORM操作实例分析
2019/12/20 PHP
获取DOM对象的几种扩展及简写
2006/10/09 Javascript
使用JavaScript switch case 另类写法
2010/03/14 Javascript
jQuery EasyUI API 中文文档 - Menu菜单
2011/10/03 Javascript
JavaScript创建对象的写法
2013/08/29 Javascript
网页运行时提示对象不支持abigimage属性或方法
2014/08/10 Javascript
Javascript获取数组中的最大值和最小值的方法汇总
2016/01/01 Javascript
基于JavaScript实现鼠标悬浮弹出跟随鼠标移动的带箭头的信息层
2016/01/18 Javascript
jQuery实现智能判断固定导航条或侧边栏的方法
2016/09/04 Javascript
详解Angular2中的编程对象Observable
2016/09/17 Javascript
实例解析js中try、catch、finally的执行规则
2017/02/24 Javascript
纯JS单页面赛车游戏制作代码分享
2017/03/03 Javascript
前端MVVM框架解析之双向绑定
2018/01/24 Javascript
nodejs多版本管理总结
2018/04/03 NodeJs
Webpack path与publicPath的区别详解
2018/05/03 Javascript
npm配置国内镜像资源+淘宝镜像的方法
2018/09/07 Javascript
关于vue的npm run dev和npm run build的区别介绍
2019/01/14 Javascript
JS可断点续传文件上传实现代码解析
2020/07/30 Javascript
python获取文件后缀名及批量更新目录下文件后缀名的方法
2014/11/11 Python
自动化Nginx服务器的反向代理的配置方法
2015/06/28 Python
Python3之手动创建迭代器的实例代码
2019/05/22 Python
将python安装信息加入注册表的示例
2019/11/20 Python
python isinstance函数用法详解
2020/02/13 Python
零基础学python应该从哪里入手
2020/08/11 Python
Python抖音快手代码舞(字符舞)的实现方法
2021/02/07 Python
CSS Grid布局教程之浏览器开启CSS Grid Layout汇总
2014/12/30 HTML / CSS
境外导游求职信
2014/02/27 职场文书
热爱祖国的演讲稿
2014/05/04 职场文书
经销商年会策划方案
2014/05/29 职场文书
Python爬取英雄联盟MSI直播间弹幕并生成词云图
2021/06/01 Python
Win10多屏显示如何设置?Win10电脑多屏显示设置操作方法
2022/07/07 数码科技