如何在Django REST Framework中显示查询参数选项 - Swagger

daj*_*jee 22 python django rest django-rest-framework

这一直困扰着我一段时间.

我的最终目标是在SwaggerUI中显示查询参数选项,并为每个查询参数提供表单输入.与为POST提供序列化程序时的显示方式类似.

我正在使用一个继承自GenericViewSet的视图集,我尝试了以下内容:

  • 提供filter_fields属性
  • 提供和设置filter_backends属性(filters.DjangoFilterBackend,)
  • 提供我的模块中定义的filter_class.
  • 覆盖options方法提供[actions][GET]信息

这是一个小问题,我没有使用任何模型,所以我不认为DjangoFilterBackend会真的帮助我.我正在使用DjangoRESTFramework与外部API进行通信,我只是简单地获取JSON结果,并将其传递给前端层.

这是我的代码的一个小修改片段,以更好地解释我的问题:

views.py

class SomeViewSet(GenericViewSet):
    # Note that I have all of these defined, but I have tried various combinations
    filter_fields = ('query_option_1', 'query_option_2',)
    filter_backeds = (filters.DjangoFilterBackend,)
    filter_class = SomeFilter
    query_metadata = some_dict

    # This works when request is OPTIONS
    def options(self, request, *args, **kwargs):
        if self.metadata_class is None:
            return self.http_method_not_allowed(request, *args, **kwargs)
        data = self.metadata_class().determine_metadata(request, self)
        data['actions']['GET'] = self.query_metadata
        return Response(data, status=status.HTTP_200_OK)
Run Code Online (Sandbox Code Playgroud)

filters.py

class SomeFilter(FilterSet):
    strict = True
    query_option_1 = django_filters.NumberFilter(name='query_option_1')
    query_option_2 = django_filters.NumberFilter(name='query_option_2')

    class Meta:
        fields = ['query_option_1', 'query_option_2']
Run Code Online (Sandbox Code Playgroud)

感谢您的关注,并提前感谢您的回复.

小智 26

新招摇

from rest_framework.filters import BaseFilterBackend
import coreapi

class SimpleFilterBackend(BaseFilterBackend):
    def get_schema_fields(self, view):
        return [coreapi.Field(
            name='query',
            location='query',
            required=False,
            type='string'
        )]

class MyViewSet(viewsets.ViewSet):
    filter_backends = (SimpleFilterBackend,)

    def list(self, request, *args, **kwargs):
        # print(request.GET.get('query'))  # Use the query param in your view
        return Response({'hello': 'world'}, status.HTTP_200_OK)
Run Code Online (Sandbox Code Playgroud)

  • 在Django rest swagger 2中这是相关的答案,因为docstrings已被弃用. (6认同)
  • 我不得不添加一个方法`filter_queryset(self,request,queryset,view)`什么都不做,因为当它试图过滤查询集时,`BaseFilterBackend`会引发`NotImplementedError`. (2认同)

daj*_*jee 20

好吧,对于那些偶然发现这个问题的人,我已经弄明白了.这是相当愚蠢的,我觉得有点愚蠢不知道,但在我的辩护中,它没有明确记录.在DRF文档中或Django REST Swagger存储库中找不到该信息.相反,它是在django-rest-framework-docs下找到的,这就是Django REST Swagger的基础.

要指定您的查询参数作为表单字段显示在SwaggerUI中,您只需这样注释:

def list(self):
    """
    param1 -- A first parameter
    param2 -- A second parameter
    """ 
    ...
Run Code Online (Sandbox Code Playgroud)

并且swagger将解析您的注释,并将为param1和param2添加表单输入.以下--是参数的描述.

  • 我尝试了您的解决方案,但查询参数既不显示默认HTML API文档也不显示[*rest_framework_swagger*](https://github.com/marcgibbons/django-rest-swagger/). (6认同)
  • **注意**这适用于招摇,但不适用于rest_framework_docs (5认同)

soo*_*oot 12

我找到了其余的框架招摇文档.所以我们可以编写参数类型(整数,字符),响应等.

三重奏---是必要的.

@api_view(["POST"])
def foo_view(request):
    """
    Your docs
    ---
    # YAML (must be separated by `---`)

    type:
      name:
        required: true
        type: string
      url:
        required: false
        type: url
      created_at:
        required: true
        type: string
        format: date-time

    serializer: .serializers.FooSerializer
    omit_serializer: false

    parameters_strategy: merge
    omit_parameters:
        - path
    parameters:
        - name: name
          description: Foobar long description goes here
          required: true
          type: string
          paramType: form
        - name: other_foo
          paramType: query
        - name: other_bar
          paramType: query
        - name: avatar
          type: file

    responseMessages:
        - code: 401
          message: Not authenticated
    """
Run Code Online (Sandbox Code Playgroud)

我们使用mixins类的情况怎么样呢ModelViewSets.我们是否需要定义list函数来添加文档? - 不

我们可以这样做:

class ArticleViewSet(viewsets.ModelViewSet):

    """
    Articles.
    ---
    list:    #<--- here!!
        parameters:
            - name: name
              description: article title
    get_price:
        omit_serializer: true

    """

    @list_route(methods=['get'])
    def get_price(self, request):
        pass
Run Code Online (Sandbox Code Playgroud)