python - coreapi - django rest framework documentation
Cómo mostrar las opciones de parámetros de consulta en Django REST Framework-Swagger (4)
Esto me ha estado molestando por un tiempo ahora.
Mi objetivo final es mostrar las opciones de parámetros de consulta dentro de SwaggerUI y dar una entrada de formulario para cada parámetro de consulta. Similar a cómo se muestra cuando se proporciona un serializador para POST.
Estoy usando un conjunto de vistas que se hereda de GenericViewSet y he intentado lo siguiente:
- proporcionar atributo
filter_fields
- proporcionar y establecer el atributo
filter_backends
en(filters.DjangoFilterBackend,)
- Proporcionar filter_class definido dentro de mi módulo.
- Omitir el método de
options
para proporcionar información de[actions][GET]
Aquí hay un pequeño problema, no estoy usando ningún modelo, así que no creo que DjangoFilterBackend realmente me ayude. Estoy usando DjangoRESTFramework para hablar con una API externa, y simplemente estoy recuperando el resultado de JSON y lo paso a la capa de frontend.
Aquí hay un pequeño fragmento modificado de mi código para explicar mejor mi problema:
vistas.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'']
Gracias por mirar, y gracias de antemano por responder.
Bien, para aquellos que se topan con esta pregunta, lo he descubierto. Es bastante tonto, y me siento un poco estúpido por no saberlo, pero en mi defensa, no estaba claramente documentado. La información no se encontró en la documentación de DRF o en el repositorio Swager de Django REST. En su lugar, se encontró en django-rest-framework-docs, que es de lo que se construye Django REST Swagger.
Para especificar su parámetro de consulta para que aparezca en su SwaggerUI como un campo de formulario, simplemente comente así:
def list(self):
"""
param1 -- A first parameter
param2 -- A second parameter
"""
...
Y swagger analizará tus comentarios y pondrá una entrada de formulario para param1 y param2. Lo que sigue --
son las descripciones de los parámetros.
Descargo de responsabilidad: estoy usando django_filters
, por lo que los resultados pueden variar. django_filters
usa los filter_fields
de filter_fields
param en el DRF ViewSet, que puede ser diferente a no usar django_filters
.
Me get_schema_fields()
este hilo y get_schema_fields()
método get_schema_fields()
en el backend de filtrado de la siguiente manera.
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
]
He encontrado el resto del marco de los documentos jactanciosos . para que podamos escribir el tipo de parámetro (interger, char), respuesta, etc.
el triple ---
es necesario
@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é hay de la situación que usamos la clase mixins como ModelViewSets
? ¿Necesitamos definir la función de list
solo para agregar los documentos? -- No
Podemos hacer así:
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
Nuevo jaleo
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)