美文网首页DjangohhhDjango学习
django-rest-framework解析请求参数

django-rest-framework解析请求参数

作者: 行如风 | 来源:发表于2017-10-20 14:51 被阅读1831次

    前言

    前面的文章中编写了接口, 调通了接口文档. 接口文档可以直接填写参数进行请求, 接下来的问题是如何接受参数, 由于请求方式与参数序列化形式的不同, 接收参数的方式也有不同.

    前提条件

    服务端我们使用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&param2=123
    这样的形式拼接在url后面.
    在request对象中
    request.query_params 中可以获取?param1=32&param2=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&param=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)
    

    最后的效果

    最终效果.png

    相关文章

      网友评论

      • 于洋_6c72:import coreapi
        其中coreapi是安装rest 框架自动安装的,
        DocParam(name = "group",required = False, description="主组id"),还可以配置参数是否必录,加入描述信息等

      本文标题:django-rest-framework解析请求参数

      本文链接:https://www.haomeiwen.com/subject/tblvuxtx.html