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.
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)
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.
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
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
]