自定義模式生成
如果默認規範生成與您希望實現的不完全匹配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
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
覆蓋將操作的描述,並記錄沒有正文和給定描述的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
的英文這僅爲通過遇到的每個序列化程序類生成一個 對象來實現的。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
明確的集合。
注: 本文作爲個人學習筆記,如有侵權,請聯繫刪除