简体   繁体   English

django-rest-swagger:如何在文档字符串中指定参数类型

[英]django-rest-swagger: How can I specify the parameter type in the docstring

I am using django-rest-framwork and django-rest-swagger.我正在使用 django-rest-framwork 和 django-rest-swagger。

The problem is that I'm fetching data directly from the body of the request:问题是我直接从请求正文中获取数据:

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']

but when I try the request from the swagger-ui I can't specify the "parameter type" (it's by default query and can't find a way to change it from the docstring)但是当我尝试来自 swagger-ui 的请求时,我无法指定“参数类型”(默认情况下它是查询并且无法找到从文档字符串中更改它的方法)

I have managed to get around my problem by changing some line in the function build_query_params_from_docstring from the file "introspectors.py" but I was wondering if there is another way to do it.我已经设法通过从文件“introspectors.py”中更改 function build_query_params_from_docstring中的某些行来解决我的问题,但我想知道是否还有另一种方法可以做到这一点。

UPDATE: This answer only works for django-rest-swagger < 2, see the comment from @krd below.更新:此答案仅适用于 django-rest-swagger < 2,请参阅下面来自 @krd 的评论。

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

If you want to put form-data:如果要放置表单数据:

def put(self, request, format=None):
    """
    This text is the description for this API.

    ---
    parameters:
    - name: username
      description: Foobar long description goes here
      required: true
      type: string
      paramType: form
    - name: password
      paramType: form
      required: true
      type: string
    """
    username = request.DATA['username']
    password = request.DATA['password']

For a JSON body you can do something like:对于 JSON 正文,您可以执行以下操作:

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

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

Define a filter-class in your viewset.在您的视图集中定义一个过滤器类。 django-rest does not do this yaml stuff for parameters anymore. django-rest 不再为参数做这个 yaml 的东西。 The fields you define in your filterclass will appear as fields in your openapi / swagger documentation.您在过滤器类中定义的字段将在您的 openapi / swagger 文档中显示为字段。 This is very neat.这是非常整洁的。

READ full documentation.阅读完整的文档。

http://www.django-rest-framework.org/apiguide/filtering/#djangofilterbackend 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()

the fields defined in the filterseet will show up in de documentation. filterseet 中定义的字段将显示在 de 文档中。 but there will be no description.但不会有任何描述。

Similar to John VanBuskirk's answer, here is what I have:类似于 John VanBuskirk 的回答,这就是我所拥有的:

The actual manual created doc:实际手动创建的文档:

drf_api/business/schema.py drf_api/business/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'
        )
    }
)

Then copied the get_swagger_view function and customized it:然后复制get_swagger_view函数并自定义:

drf_api/swagger.py 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()

Then hook it up to the urls.py然后将其连接到 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),

The only way I've had success in defining parameter types is by creating a view that defines what I want without using the generator.我在定义参数类型方面取得成功的唯一方法是在不使用生成器的情况下创建一个定义我想要的内容的视图。

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'
        ),
    }
)

and then using that class in urls.py然后在 urls.py 中使用该类

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

For latest django-rest-framework > 3.7 and django-rest-swagger > 2 , go through the below link to find working solution对于最新的django-rest-framework > 3.7django-rest-swagger > 2 ,请通过以下链接找到工作解决方案

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

For Django Rest Framework >= 2.0对于 Django Rest 框架 >= 2.0

I am using a serializer and apply to a the view function with a decorator:我正在使用序列化程序并应用到带有装饰器的视图函数:

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

Then in the function I use:然后在我使用的函数中:

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

And works!!!并且有效!!!

[enter image description here][1]For me it worked with the ManualSchema . [在此处输入图像描述][1]对我来说,它与ManualSchema一起使用。 You have to define the description and fields.您必须定义描述和字段。 See:看:

from rest_framework import views
import coreapi
import coreschema
from rest_framework.schemas import ManualSchema

class RegisterView(views.APIView):

    schema = ManualSchema(
        description="User register endpoint.",
        fields=[
            coreapi.Field(
                'username',
                required=True,
                location='path',
                description='A unique username',
                schema=coreschema.String(),
                ),
            coreapi.Field(
                'password',
                required=True,
                location='path',
                schema=coreschema.String(),
                ),
            ]
        )

    )
    ...


声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM