django-rest-swagger:如何在docstring中指定参数类型

时间:2014-11-09 19:47:34

标签: python django-rest-framework

我正在使用django-rest-framwork和django-rest-swagger。

问题是我直接从请求正文中获取数据:

def put(self, request, format=None):
    """                                                                                                                                                                                                
    This text is the description for this API                                                                                                                                                          
    username -- username                                                                                                                                                                               
    password -- password                                                                                                                                                                               
    """
    username = request.DATA['username']
    password = request.DATA['password']

但是当我尝试来自swagger-ui的请求时,我无法指定"参数类型" (它是默认查询,无法找到从文档字符串中更改它的方法)

我设法通过从文件" introspectors.py" 更改函数 build_query_params_from_docstring 中的某些行来解决我的问题,但我想知道如果有另一种方法可以做到这一点。

6 个答案:

答案 0 :(得分:9)

更新:此答案仅适用于django-rest-swagger< 2,请参阅下面@krd的评论。

文档:http://django-rest-swagger.readthedocs.org/en/latest/yaml.html

如果你想填写表格数据:

def put(...):
    """
    ...

    ---
    parameters:
    - name: body
      description: JSON object containing two strings: password and username.
      required: true
      paramType: body
      pytype: RequestSerializer
    """
    ...

对于JSON正文,您可以执行以下操作:

{{1}}

答案 1 :(得分:1)

在视图集中定义过滤器类。 django-rest不再为参数做yaml东西了。您在过滤器类中定义的字段将在openapi / swagger文档中显示为字段。这非常整洁。

阅读完整文档。

http://www.django-rest-framework.org/apiguide/filtering/#djangofilterbackend

from django_filters.rest_framework.filterset import FilterSet

class ProductFilter(FilterSet):

    class Meta(object):
        models = models.Product
        fields = (
            'name', 'category', 'id', )


class PurchasedProductsList(generics.ListAPIView):
    """
    Return a list of all the products that the authenticated
    user has ever purchased, with optional filtering.
    """
    model = Product
    serializer_class = ProductSerializer
    filter_class = ProductFilter

    def get_queryset(self):
        user = self.request.user
        return user.purchase_set.all()

filterseet中定义的字段将显示在de documentation中。 但是没有描述。

答案 2 :(得分:1)

与John VanBuskirk的答案类似,这就是我所拥有的:

实际手册创建了doc:

drf_api /商业/ schema.py

# encoding: utf-8
from __future__ import unicode_literals
from __future__ import absolute_import
import coreapi

schema = coreapi.Document(
    title='Business Search API',
    url='/api/v3/business/',
    content={
        'search': coreapi.Link(
            url='/',
            action='get',
            fields=[
                coreapi.Field(
                    name='what',
                    required=True,
                    location='query',
                    description='Search term'
                ),
                coreapi.Field(
                    name='where',
                    required=True,
                    location='query',
                    description='Search location'
                ),
            ],
            description='Search business listings'
        )
    }
)

然后复制了get_swagger_view函数并对其进行了自定义:

drf_api / swagger.py

# encoding: utf-8
from __future__ import unicode_literals
from __future__ import absolute_import
from rest_framework import exceptions
from rest_framework.permissions import AllowAny
from rest_framework.renderers import CoreJSONRenderer
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_swagger import renderers
from django.utils.module_loading import import_string


def get_swagger_view(schema_location):
    """
    Returns schema view which renders Swagger/OpenAPI.
    """
    class SwaggerSchemaView(APIView):
        _ignore_model_permissions = True
        exclude_from_schema = True
        permission_classes = [AllowAny]
        renderer_classes = [
            CoreJSONRenderer,
            renderers.OpenAPIRenderer,
            renderers.SwaggerUIRenderer
        ]

        def get(self, request):
            schema = None

            try:
                schema = import_string(schema_location)
            except:
                pass

            if not schema:
                raise exceptions.ValidationError(
                    'The schema generator did not return a schema Document'
                )

            return Response(schema)


    return SwaggerSchemaView.as_view()

然后将其连接到urls.py

from ..swagger import get_swagger_view
from . import views

schema_view = get_swagger_view(schema_location='drf_api.business.schema.schema')

urlpatterns = [
    url(r'^swagger/$', schema_view),

答案 3 :(得分:0)

我在定义参数类型方面取得成功的唯一方法是创建一个视图,在不使用生成器的情况下定义我想要的内容。

class SwaggerSchemaView(APIView):
permission_classes = [IsAuthenticatedOrReadOnly,]
renderer_classes = [renderers.OpenAPIRenderer, renderers.SwaggerUIRenderer]

schema = coreapi.Document(
    title='Thingy API thing',
        'range': coreapi.Link(
            url='/range/{start}/{end}',
            action='get',
            fields=[
                coreapi.Field(
                    name='start',
                    required=True,
                    location='path',
                    description='start time as an epoch',
                    type='integer'
                ),
                coreapi.Field(
                    name='end',
                    required=True,
                    location='path',
                    description='end time as an epoch',
                    type='integer'
                )
            ],
            description='show the things between the things'
        ),
    }
)

然后在urls.py中使用该类

urlpatterns = [
    url(r'^$', SwaggerSchemaView.as_view()),
    ...
]

答案 4 :(得分:0)

对于最新的django-rest-framework > 3.7django-rest-swagger > 2,请通过以下链接找到可行的解决方案

https://github.com/marcgibbons/django-rest-swagger/issues/549#issuecomment-371860030

答案 5 :(得分:0)

对于Django Rest Framework> = 2.0

我正在使用序列化器,并使用装饰器将其应用于view函数:

from types import MethodType
from typing import Optional, List, Callable, Any

from rest_framework.decorators import api_view as drf_api_view
from rest_framework.serializers import BaseSerializer

Function = Callable[..., Any]


def api_view(
    http_method_names: Optional[List[str]] = None,
    use_serializer: Optional[BaseSerializer] = None
) -> Function:
    if use_serializer is None:
        return drf_api_view(http_method_names)

    def api_view_deco_wrap(view: Function) -> Function:
        nonlocal http_method_names, use_serializer

        decorated_view = drf_api_view(http_method_names)(view)

        if use_serializer:
            decorated_view.cls.get_serializer = \
                MethodType(lambda s: use_serializer(), decorated_view.cls)

        return decorated_view

    return api_view_deco_wrap

然后在我使用的功能中:

@util.api_view(["POST"], use_serializer=serializers.MySerializer)
def replace(request, pk):
    pass

工作正常!