Django Rest Framework 使用 Swagger 或其他文档自定义 POST URL 具有已定义参数 (request.POST) 的端点
Django Rest Framework custom POST URL endpoints with defined parameter (request.POST) with Swagger or other doc
之前在 Django 1.11 中,我这样定义 Django REST API:
在url.py
url(r'^api/test_token$', api.test_token, name='test_token'),
在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)
现在我正在迁移到 Django 3.1.5,我想知道如何使用 Django Rest Framework (DRF) 以同样的方式实现上述目标。在上面的特殊情况下,它是 POST API "test_token" 接受一个参数。并生成 API 文档,例如 swagger/redoc(可用于测试 API)
一些注意事项:
- 这里还指出 django-rest-swagger 已于 2019 年 6 月弃用
- 值得注意的是,它使用 request.POST(表单数据)作为参数 https://www.django-rest-framework.org/tutorial/2-requests-and-responses/
- 在 Django 1.11.x 我正在使用这个 swagger_schema.py - https://gist.github.com/axilaris/b7152215a76f6f1f5ffca0436991328d
如何在 Django 3.x 上实现它? (如标题所示:Django Rest Framework custom POST URL endpoints with defined parameter with Swagger or other doc)
更新:
我认为这里有某种形式的解决方案:
https://github.com/tfranzel/drf-spectacular/issues/279
因为我有很多使用@api_view 的API,更改文档字符串
装饰器 @extend_schema 可能是最简单的迁移路径。我希望有人可以提供有关 url.py 到使用 @extend_schema 转换的指导。这是为了实现 url 端点和 swagger。谢谢。
这是我与 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)
它给出了这个(这是不正确的),请注意令牌查询
curl -X POST "http://localhost:8000/api/test_token/?token=hello" -H "accept: application/json" -H "X-CSRFToken: JyPOSAQx04LK0aM8IUgUmkruALSNwRbeYDzUHBhCjtXafC3tnHRFsxvyg5SgMLhI" -d ""
而不是 POST 输入参数(如何获取?)
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/
解决方案:
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_urlpatterns
如您所说,django-rest-swagger 已弃用。
这就是为什么建议使用 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):
...
或者如果您想使用 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):
...
或 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):
pass
你的 url.py 看起来像这样
# 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'),
]
如果您只是想要一些东西来测试 API,Django 休息框架实际上带有它自己的可浏览 API。如果您在 APIView
上设置 serializer_class
,那么 BrowsableAPIRenderer
将为您计算出所有相关细节。
以下应该可以解决问题:
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")
]
(请注意,在 Django 2+ 中我们使用 path
而不是旧的 url
模式。如果您仍想使用正则表达式模式,可以使用 path_re
)。
以上假定您没有更改渲染器的默认设置。默认值为:
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
]
}
只要浏览到相关端点,您就会有一个不错的测试界面。
在幕后,serializer_class
的设置使它成为可能。这与 DRF 自动生成用于 swagger 或 redoc 之类的模式的方式相同。
之前在 Django 1.11 中,我这样定义 Django REST API:
在url.py
url(r'^api/test_token$', api.test_token, name='test_token'),
在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)
现在我正在迁移到 Django 3.1.5,我想知道如何使用 Django Rest Framework (DRF) 以同样的方式实现上述目标。在上面的特殊情况下,它是 POST API "test_token" 接受一个参数。并生成 API 文档,例如 swagger/redoc(可用于测试 API)
一些注意事项:
- 这里还指出 django-rest-swagger 已于 2019 年 6 月弃用
- 值得注意的是,它使用 request.POST(表单数据)作为参数 https://www.django-rest-framework.org/tutorial/2-requests-and-responses/
- 在 Django 1.11.x 我正在使用这个 swagger_schema.py - https://gist.github.com/axilaris/b7152215a76f6f1f5ffca0436991328d
如何在 Django 3.x 上实现它? (如标题所示:Django Rest Framework custom POST URL endpoints with defined parameter with Swagger or other doc)
更新:
我认为这里有某种形式的解决方案: https://github.com/tfranzel/drf-spectacular/issues/279
因为我有很多使用@api_view 的API,更改文档字符串 装饰器 @extend_schema 可能是最简单的迁移路径。我希望有人可以提供有关 url.py 到使用 @extend_schema 转换的指导。这是为了实现 url 端点和 swagger。谢谢。
这是我与 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)
它给出了这个(这是不正确的),请注意令牌查询
curl -X POST "http://localhost:8000/api/test_token/?token=hello" -H "accept: application/json" -H "X-CSRFToken: JyPOSAQx04LK0aM8IUgUmkruALSNwRbeYDzUHBhCjtXafC3tnHRFsxvyg5SgMLhI" -d ""
而不是 POST 输入参数(如何获取?)
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/
解决方案:
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_urlpatterns
如您所说,django-rest-swagger 已弃用。
这就是为什么建议使用 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):
...
或者如果您想使用 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):
...
或 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):
pass
你的 url.py 看起来像这样
# 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'),
]
如果您只是想要一些东西来测试 API,Django 休息框架实际上带有它自己的可浏览 API。如果您在 APIView
上设置 serializer_class
,那么 BrowsableAPIRenderer
将为您计算出所有相关细节。
以下应该可以解决问题:
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")
]
(请注意,在 Django 2+ 中我们使用 path
而不是旧的 url
模式。如果您仍想使用正则表达式模式,可以使用 path_re
)。
以上假定您没有更改渲染器的默认设置。默认值为:
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
]
}
只要浏览到相关端点,您就会有一个不错的测试界面。
在幕后,serializer_class
的设置使它成为可能。这与 DRF 自动生成用于 swagger 或 redoc 之类的模式的方式相同。