如果默认规范生成与您希望实现的不完全匹配drf-yasg
,则默认提供一些自定义行为挂钩。
可以您通过将其类级swagger_schema
属性设置为阻止视图所有游戏在扬鞭视图中None
,可以或者通过auto_schema
在@swagger_auto_schema中将其覆盖设置为无 来阻止包含操作:
class UserList(APIView):
swagger_schema = None
# all methods of the UserList class will be excluded
...
# only the GET method will be shown in Swagger
@swagger_auto_schema(method='put', auto_schema=None)
@swagger_auto_schema(methods=['get'], ...)
@api_view(['GET', 'PUT'])
def user_detail(request, pk):
pass
@swagger_auto_schema
装饰可以您在视图函数上使用装饰器来覆盖生成的某些属性。例如,在一中,@swagger_auto_schema
Operation
ViewSet
@swagger_auto_schema(operation_description="partial_update description override", responses={404: 'slug not found'})
def partial_update(self, request, *args, **kwargs):
"""partial_update method docstring"""
...
覆盖将操作的描述,并记录没有正文和给定描述的404响应。PATCH /article/{id}/
可以您在哪里‧使用装饰器取决于您的视图类型:@swagger_auto_schema
对于基于函数的@api_view
S,因为相同的视图可以处理多个方法,因此代表多个操作,如果要覆盖不同的操作,则必须多次添加装饰器:
test_param = openapi.Parameter('test', openapi.IN_QUERY, description="test manual param", type=openapi.TYPE_BOOLEAN) user_response = openapi.Response('response description', UserSerializer) # 'method' can be used to customize a single HTTP method of a view @swagger_auto_schema(method='get', manual_parameters=[test_param], responses={200: user_response}) # 'methods' can be used to apply the same modification to multiple methods @swagger_auto_schema(methods=['put', 'post'], request_body=UserSerializer) @api_view(['GET', 'PUT', 'POST']) def user_detail(request, pk): ...
对于基于类APIView
,GenericAPIView
状语从句:非ViewSet
衍生物,你必须装饰每个操作的相应方法:
class UserList(APIView): @swagger_auto_schema(responses={200: UserSerializer(many=True)}) def get(self, request): ... @swagger_auto_schema(operation_description="description") def post(self, request): ...
为ViewSet
, ,GenericViewSet
,ModelViewSet
每个因为集视图对应于多个路径,必须则装饰作用英文的方法,即list
,create
,retrieve
等。
此外,@action
S,@ list_route` 秒或@detail_route
在视图集定义,例如基于函数API视图S,可以响应多个HTTP方法因此具有必须单独修饰的多个操作:
class ArticleViewSet(viewsets.ModelViewSet): # method or 'methods' can be skipped because the list_route only handles a single method (GET) @swagger_auto_schema(operation_description='GET /articles/today/') @action(detail=False, methods=['get']) def today(self, request): ... @swagger_auto_schema(method='get', operation_description="GET /articles/{id}/image/") @swagger_auto_schema(method='post', operation_description="POST /articles/{id}/image/") @action(detail=True, methods=['get', 'post'], parser_classes=(MultiPartParser,)) def image(self, request, id=None): ... @swagger_auto_schema(operation_description="PUT /articles/{id}/") def update(self, request, *args, **kwargs): ... @swagger_auto_schema(operation_description="PATCH /articles/{id}/") def partial_update(self, request, *args, **kwargs): ...
小费
如果你想自定义你自己没有实现的方法的生成,你可以 swagger_auto_schema
结合使用Django method_decorator
:
@method_decorator(name='list', decorator=swagger_auto_schema(
operation_description="description from swagger_auto_schema via method_decorator"
))
class ArticleViewSet(viewsets.ModelViewSet):
...
这样可以避免不必要地覆盖该方法。
小费
您可以更进一步直接装饰结果as_view
,与方法覆盖@api_view
如上所述相同:
decorated_login_view = \
swagger_auto_schema(
method='post',
responses={status.HTTP_200_OK: LoginResponseSerializer}
)(LoginView.as_view())
urlpatterns = [
...
url(r'^login/$', decorated_login_view, name='login')
]
可以这让您避免完全跳过不必要的子类。
警告
但是,请注意上述两种方法都可以通过替换基类本身上的/装饰方法来产生意外(也许是令人惊讶的)结果。
Meta
嵌套类可以您通过向序列化程序添加Meta
类来定义一些每序列化程序选项对话,例如:
class WhateverSerializer(Serializer):
...
class Meta:
... options here ...
可用选项包括:
ref_name
- 一个字符串,将用作此序列化程序类的模型定义名称; 将其设置为None
将强制序列化程序在所使用的任何位置生成为内联模型。如果两个序列化程序具有相同的ref_name
,则它们的用法将被替换为对相同定义的引用。如果未指定此选项,则所有序列化程序都具有从其类名派生的隐式名称,减去任何Serializer
后缀(例如UserSerializer
- >User
,SerializerWithSuffix
- >SerializerWithSuffix
)swagger_schema_fields
- 将字段名称映射到值的字典。这些属性将在从中生成的对象上设置。字段名称必须是python值,根据它们转换为Swagger 属性名称。属性名称和值必须符合 OpenAPI 2.0规范。Schema
Schema
Serializer
Schema
make_swagger_name()
SwaggerAutoSchema
对于更高级的控制,您可以进行子类化- 请参阅文档页面以获取可以覆盖的方法列表。SwaggerAutoSchema
您可以通过使用上述@swagger_auto_schema 装饰器在视图方法上设置自定义子类,其将设置为swagger_schema
视图类上指定的类级属性,或 通过设置全局设置子类来使用 。
例如,要生成所有操作ID为camel case,您可以执行以下操作:
from inflection import camelize
class CamelCaseOperationIDAutoSchema(SwaggerAutoSchema):
def get_operation_id(self, operation_keys):
operation_id = super(CamelCaseOperationIDAutoSchema, self).get_operation_id(operation_keys)
return camelize(operation_id, uppercase_first_letter=False)
SWAGGER_SETTINGS = {
'DEFAULT_AUTO_SCHEMA_CLASS': 'path.to.CamelCaseOperationIDAutoSchema',
...
}
OpenAPISchemaGenerator
如果您需要控制比对象更高级别的东西(例如整体文档结构,元数据中的供应商扩展),您也可以再次进行子类化- 请参阅文档页面以获取其方法列表。Operation
OpenAPISchemaGenerator
自这个定义生成器可以通过把它设置为使用一个的使用。generator_class
SchemaView
get_schema_view()
Inspector
类对于定制相关的特定领域,串行器,过滤器或分页程序类行为可以实施,,, 班并与使用它们@swagger_auto_schema 或一个 相关的设置。FieldInspector
SerializerInspector
FilterInspector
PaginatorInspector
像可以实现这样为所有参数添加描述的一个 :FilterInspector
DjangoFilterBackend
class DjangoFilterDescriptionInspector(CoreAPICompatInspector):
def get_filter_parameters(self, filter_backend):
if isinstance(filter_backend, DjangoFilterBackend):
result = super(DjangoFilterDescriptionInspector, self).get_filter_parameters(filter_backend)
for param in result:
if not param.get('description', ''):
param.description = "Filter the returned list by {field_name}".format(field_name=param.name)
return result
return NotHandled
@method_decorator(name='list', decorator=swagger_auto_schema(
filter_inspectors=[DjangoFilterDescriptionInspector]
))
class ArticleViewSet(viewsets.ModelViewSet):
filter_backends = (DjangoFilterBackend,)
filter_fields = ('title',)
...
第二个例子,它从所有生成的对象中删除属性 :FieldInspector
title
Schema
class NoSchemaTitleInspector(FieldInspector):
def process_result(self, result, method_name, obj, **kwargs):
# remove the `title` attribute of all Schema objects
if isinstance(result, openapi.Schema.OR_REF):
# traverse any references and alter the Schema object in place
schema = openapi.resolve_ref(result, self.components)
schema.pop('title', None)
# no ``return schema`` here, because it would mean we always generate
# an inline `object` instead of a definition reference
# return back the same object that we got - i.e. a reference if we got a reference
return result
class NoTitleAutoSchema(SwaggerAutoSchema):
field_inspectors = [NoSchemaTitleInspector] + swagger_settings.DEFAULT_FIELD_INSPECTORS
class ArticleViewSet(viewsets.ModelViewSet):
swagger_schema = NoTitleAutoSchema
...
注意
关于引用的注释 - 对象有时通过引用()输出; 实际上,这就是在OpenAPI中实现命名模型的方式:Schema
SchemaRef
- 在输出文件中,一个有
definitions
所有游戏所有模型对象的部分Schema
- 模型的每个用法都引用该单个对象 - 例如,在上面的ArticleViewSet中,包含模型的所有请求和响应都将引用相同的模式定义。
Schema
Article
'$ref': '#/definitions/Article'
的英文这仅为通过遇到的每个序列化程序类生成一个 对象来实现的。Schema
意味着这FieldInspector
如果您正在处理引用(也称为命名模型),通常应该避免使用视图或特定于方法的S,因为您永远不会知道哪个视图将是第一个为给定序列化程序生成模式的视图。
重要信息:ModelSerializer
从模型生成的小号 上的嵌套字段ForeignKeys
将始终按值输出。如果你想要通过引用行为,你必须明确地设置嵌套字段的序列化器类,而让它不是ModelSerializer
自动生成一个; 例如:
class OneSerializer(serializers.ModelSerializer):
class Meta:
model = SomeModel
fields = ('id',)
class AnotherSerializer(serializers.ModelSerializer):
chilf = OneSerializer()
class Meta:
model = SomeParentModel
fields = ('id', 'child')
另一个由此产生的警告是,任何名为“ NestedSerializer
”的序列化程序都将被强制内联,它除非有ref_name
明确的集合。