Comment afficher les options des paramètres de requête dans Django REST Framework-Swagger

cela me dérange depuis un moment maintenant.

mon but ultime est de montrer les options des paramètres de requête à L'intérieur de SwaggerUI et de donner une entrée de forme pour chaque paramètre de requête. Similaire à la façon dont il est affiché lors de la fourniture d'un serializer pour POST.

j'utilise un viewset qui hérite de GenericViewSet et j'ai essayé ce qui suit:

  • donner filter_fields l'attribut
  • fournir et set filter_backends l'attribut de (filters.DjangoFilterBackend,)
  • provide filter_class défini dans mon module.
  • Remplacer options méthode pour fournir [actions][GET] information

voici un petit hic, je n'utilise aucun modèle donc je ne pense pas que DjangoFilterBackend va vraiment m'aider. J'utilise Djangorestfram Framework pour parler à une API externe, et je ne fais que récupérer le résultat JSON, et le transmettre à la couche frontend.

voici un petit extrait modifié de mon code pour mieux expliquer mon problème:

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)

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

Merci d'avoir regardé, et merci d'avance d'avoir répondu.

19
demandé sur dajee 2015-01-29 00:50:09

4 réponses

Nouveau swagger

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):
        return Response({'hello': 'world'}, status.HTTP_200_OK)
24
répondu vadimchin 2017-01-23 10:25:27

D'accord, pour ceux qui trébuchent sur cette question, je l'ai compris. C'est assez stupide, et je me sens un peu stupide de ne pas le savoir, mais pour ma défense, ce n'était pas clairement documenté. L'information n'a pas été trouvée dans la documentation du DRF, ni dans le référentiel Django REST Swagger. Au lieu de cela, il a été trouvé sous django-rest-framework-docs, qui est ce que Django REST Swagger est construit sur.

pour spécifier votre paramètre de requête pour apparaître dans votre SwaggerUI comme un champ de forme, vous commentaire simplement comme ceci:

def list(self):
    """
    param1 -- A first parameter
    param2 -- A second parameter
    """ 
    ...

et swagger analysera vos commentaires et mettra un formulaire en entrée pour param1 et param2. Ce qui suit -- la description des paramètres.

20
répondu dajee 2015-01-29 03:00:47

j'ai trouvé reste de cadre swagger docs. nous pouvons donc écrire le type de paramètre (interger, char), la réponse, etc.

la triple --- est nécessaire.

@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
    """

Qu'en est-il de la situation dans laquelle nous utilisons la classe mixins telle que ModelViewSets. Devons-nous définir l' list fonction pour ajouter les docs? -- Pas de

On peut faire comme ceci:

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
11
répondu soooooot 2015-07-06 08:12:41

Disclaimer: je suis à l'aide de django_filters utilise le param filter_fields dans le ViewSet DRF, ce qui peut être différent de ne pas utiliser django_filters.

j'ai pris l'inspiration de ce fil et emportait l' get_schema_fields() méthode dans le filtrage backend de la manière suivante.

settings.py

REST_FRAMEWORK = {
    ...
    'DEFAULT_FILTER_BACKENDS': ('location.of.custom_backend.CustomDjangoFilterBackend')
    ...
}

custom_backend.py

import coreapi
import coreschema
from django_filters.rest_framework import DjangoFilterBackend


class CustomDjangoFilterBackend(DjangoFilterBackend):
    """
    Overrides get_schema_fields() to show filter_fields in Swagger.
    """

    def get_schema_fields(self, view):
        assert (
            coreapi is not None
        ), "coreapi must be installed to use `get_schema_fields()`"
        assert (
            coreschema is not None
        ), "coreschema must be installed to use `get_schema_fields()`"

        # append filter fields to existing fields
        fields = super().get_schema_fields(view)
        if hasattr(view, "filter_fields"):
            fields += view.filter_fields

        return [
            coreapi.Field(
                name=field,
                location='query',
                required=False,
                type='string',
            ) for field in fields
        ]
1
répondu Sean Chon 2018-08-07 00:48:38