anteriormente en Django 1.11, definí la API REST de Django de esta manera:
en url.py
url(r'^api/test_token$', api.test_token, name='test_token'),en api.py
@api_view(['POST']) def test_token(request): # ----- YAML below for Swagger ----- """ description: test_token parameters: - name: token type: string required: true location: form """ token = request.POST['token'] return Response("test_token success", status=status.HTTP_200_OK)Ahora que estoy migrando a Django 3.1.5, me gustaría saber cómo se puede lograr lo anterior de la misma manera con Django Rest Framework (DRF). En el caso particular anterior, es POST API "test_token" que toma un parámetro. Y genere documentación de API como swagger/redoc (que se puede usar para probar la API)
Algunas notas:
¿Cómo puedo implementar esto en Django 3.x? (como en el título: Puntos finales de URL POST personalizados de Django Rest Framework con parámetro definido con Swagger u otro documento)
ACTUALIZAR:
Creo que hay algún tipo de solución desde aquí: https://github.com/tfranzel/drf-spectacular/issues/279
Como tengo muchas API que usan @api_view, la cadena de documentación de cambios al decorador @extend_schema puede ser la ruta de migración más simple. Espero que alguien pueda brindar orientación sobre url.py para la conversión usando @extend_schema. Esto es para implementar los puntos finales de URL y swagger. Gracias.
Sin embargo, esto es lo más cercano que tengo con drf-spectacular
@extend_schema( parameters=[OpenApiParameter( name='token', type={'type': 'string'}, location=OpenApiParameter.QUERY, required=False, style='form', explode=False, )], responses=OpenApiTypes.OBJECT, ) @api_view(['POST']) def test_api(request): # ----- YAML below for Swagger ----- """ description: test_api parameters: - name: token type: string required: true location: form """ token = request.POST['token'] return Response("success test_api:" + token, status=status.HTTP_200_OK)está dando esto (que es incorrecto), observe la consulta del token
curl -X POST "http://localhost:8000/api/test_token/?token=hello" -H "accept: application/json" -H "X-CSRFToken: JyPOSAQx04LK0aM8IUgUmkruALSNwRbeYDzUHBhCjtXafC3tnHRFsxvyg5SgMLhI" -d ""en lugar de un parámetro de entrada POST (¿cómo obtener esto?)
curl -X POST --header 'Content-Type: application/x-www-form-urlencoded' --header 'Accept: application/json' --header 'X-CSRFToken: aExHCSwrRyStDiOhkk8Mztfth2sqonhTkUFaJbnXSFKXCynqzDQEzcRCAufYv6MC' -d 'token=hello' 'http://localhost:8000/api/test_token/LA SOLUCIÓN:
url.py
from drf_yasg.utils import swagger_auto_schema from rest_framework.response import Response from rest_framework import status from rest_framework.decorators import parser_classes from rest_framework.parsers import FormParser token = openapi.Parameter('token', openapi.IN_FORM, type=openapi.TYPE_STRING, required=True) something = openapi.Parameter('something', openapi.IN_FORM, type=openapi.TYPE_INTEGER, required=False) @swagger_auto_schema( method="post", manual_parameters=[token, something], operation_id="token_api" ) @api_view(['POST']) # this is optional and insures that the view gets formdata @parser_classes([FormParser]) def token_api(request): token = request.POST['token'] something = request.POST['something'] return Response("success test_api:" + token + something, status=status.HTTP_200_OK) schema_view = get_schema_view( openapi.Info( title="Snippets API", default_version='v1', description="Test description", terms_of_service="https://www.google.com/policies/terms/", contact=openapi.Contact(email="contact@snippets.local"), license=openapi.License(name="BSD License"), ), public=True, permission_classes=[permissions.AllowAny], ) urlpatterns = [ path('token_api', token_api, name='token_api'), path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), ] + required_urlpatternsComo dijiste, django-rest-swagger está en desuso.
Por eso se recomienda usar drf-yasg .
from drf_yasg import openapi from drf_yasg.utils import swagger_auto_schema class ArticleViewSet(viewsets.ModelViewSet): @swagger_auto_schema(request_body=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'test_token': openapi.Schema(type=openapi.TYPE_STRING, description='string'), } )) def create(self, request, *args, **kwargs): ...O si desea utilizar una acción DRF
@swagger_auto_schema(method="post", request_body=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'test_token': openapi.Schema(type=openapi.TYPE_STRING, description='string'), } )) @action(method=["post"], detail=False) def my_post_action(self, request, *args, **kwargs): ...O con vista api:
# here we define that this view accepts a json (or object parameter) that has test_token parameter inside of it @swagger_auto_schema(method='post', request_body=openapi.Schema( type=openapi.TYPE_OBJECT, # object because the data is in json format properties={ 'test_token': openapi.Schema(type=openapi.TYPE_STRING, description='this test_token is used for...'), } ), operation_id="token_view") # your view @api_view(['POST']) def token_view(request): passY tu url.py se verá así
# define some basic info about your api for swagger schema_view = get_schema_view( openapi.Info( title="Snippets API", default_version='v1', description="Test description", terms_of_service="https://www.google.com/policies/terms/", contact=openapi.Contact(email="contact@snippets.local"), license=openapi.License(name="BSD License"), ), public=True, permission_classes=[permissions.AllowAny], ) urlpatterns = [ # define your api view url path('token_view/', token_view), # define the url of the swagger ui url(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), ]Si solo desea algo para probar la API, Django rest framework en realidad viene con su propia API navegable. Si configura un serializer_class en su APIView , entonces el BrowsableAPIRenderer descubrirá todos los detalles relevantes por usted.
Lo siguiente debería hacer el truco:
from rest_framework import serializers, status from rest_framework.response import Response from rest_framework.generics import GenericAPIView class MySerializer(serializers.Serializer): token = serializers.CharField() class MyView(GenericAPIView): serializer_class = MySerializer def post(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) data = serializer.data return Response("test_token success", status=status.HTTP_200_OK) # urls.py urlpatterns = [ ... path("api/test_token", views.MyView.as_view(), name="test_token") ] (Tenga en cuenta que en Django 2+ usamos path en lugar del antiguo patrón de url . Si aún desea usar patrones de expresiones regulares, puede usar path_re ).
Lo anterior supone que no ha cambiado la configuración predeterminada de los renderizadores. El valor predeterminado es:
REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': [ 'rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.BrowsableAPIRenderer', ] }Simplemente navegue hasta el punto final relevante y tendrá una buena interfaz para realizar pruebas.
Debajo del capó, es el hecho de que serializer_class está configurado lo que permite esto. Esta es la misma forma en que DRF generará automáticamente un esquema para usar con algo como swagger o redoc.