嵌套序列化程序的 Yasg 架构生成显示不正确 requests/responses
Yasg schema generation for nested serializer shows incorrect requests/responses
我有一个 Django API,我尝试使用 drf-yasg 创建文档。我在为我的嵌套序列化程序和 ListAPI 视图自动生成的模式时遇到问题。它看起来像这样:
serializers.py
class SlideDataSerializer(serializers.ModelSerializer):
description = SlideDataDescriptionSerializer(many=True, read_only=True, source='slidedatadescription_set')
class Meta:
model = SlideData
fields = ['catch', 'title', 'description', 'icon']
class SlideSerializer(serializers.ModelSerializer):
datas = SlideDataSerializer(many=True, read_only=True, source='slidedata_set')
class Meta:
model = Slide
fields = ['datas']
class PlanDataDescriptionSerializer(serializers.ModelSerializer):
class Meta:
model = PlanDataDescription
fields = ['description']
class PlanDataSerializer(serializers.ModelSerializer):
description = PlanDataDescriptionSerializer(many=True, read_only=True, source='plandatadescription_set')
class Meta:
model = PlanData
fields = ['stripColor', 'name', 'description', 'pricePerMonth', 'currency', 'picture']
class PlanSerializer(serializers.ModelSerializer):
datas = PlanDataSerializer(many=True, read_only=True, source='plandata_set')
class Meta:
model = Plan
fields = ['mainTitle', 'datas']
views.py
class ProjectList(generics.ListAPIView):
permission_classes = [permissions.AllowAny]
serializer_class_slide = SlideSerializer
serializer_class_plan = PlanSerializer
def get_queryset_object(self, Table, campaign, lang):
queryset = Table.objects.filter(campaign__name=campaign).filter(language__alpha2=lang)
return queryset[0]
def list(self, request):
Tables = [Slide,
Plan]
campaign = self.request.query_params.get('campaign') or "default"
lang = self.request.query_params.get('lang') or "en"
if not all(Table.objects.filter(campaign__name=campaign).filter(language__alpha2=lang) for Table in Tables):
campaign = "default"
if not all(Table.objects.filter(campaign__name=campaign).filter(language__alpha2=lang) for Table in Tables):
lang = "en"
slides = self.serializer_class_slide(self.get_queryset_object(Slide, campaign, lang))
plans = self.serializer_class_plan(self.get_queryset_object(Plan, campaign, lang))
return Response({
"slides": slides.data,
"plans": plans.data,
})
和 urls.py:
openapi_info = openapi.Info(
title="Projectname",
default_version="v1",
description="Endpoints",
terms_of_service="TBD",
contact=openapi.Contact(email="abc@123.com"),
license=openapi.License(name="BSD License"),
)
schema_view = get_schema_view(
openapi_info,
public=True,
permission_classes=(permissions.AllowAny,),
)
API_VERSION = 'v1'
urlpatterns = [
path('swagger/', schema_view.with_ui(
'swagger', cache_timeout=0), name='schema-swagger-ui'),
path('swagger/api.json', schema_view.without_ui( cache_timeout=0), name='schema-swagger-json'),
]
端点工作正常,但 swagger 没有创建正确的请求或响应,当我访问它时它给我这个错误消息:
view's ProjectList raised exception during schema generation; use `getattr(self, 'swagger_fake_view', False)` to detect and short-circuit this
Traceback (most recent call last):
File "/home/projects/env/lib/python3.8/site-packages/drf_yasg/inspectors/base.py", line 42, in call_view_method
return view_method()
File "/home/projects/env/lib/python3.8/site-packages/rest_framework/generics.py", line 108, in get_serializer
serializer_class = self.get_serializer_class()
File "/home/projects/env/lib/python3.8/site-packages/rest_framework/generics.py", line 122, in get_serializer_class
assert self.serializer_class is not None, (
AssertionError: 'ProjectList' should either include a `serializer_class` attribute, or override the `get_serializer_class()` method.
我不能包含一个序列化器 class 名称,因为我使用多个序列化器,我不能为此创建一个序列化器,因为它们被分成不同的模型。覆盖 get_serializer_class() 没有用,因为我也不知道如何将这些序列化器合并到那里。我怎样才能使这种表现形式发挥作用?提前致谢
这是因为您没有添加 class 的 Serializer 。您添加的那些序列化程序不是内置的。只需添加
serializer_class = SlideSerializer
到您的 class 变量,即使您不想使用它。如错误所述,您需要将 serializer_class 添加到您的 ListAPIView 。
我有一个 Django API,我尝试使用 drf-yasg 创建文档。我在为我的嵌套序列化程序和 ListAPI 视图自动生成的模式时遇到问题。它看起来像这样:
serializers.py
class SlideDataSerializer(serializers.ModelSerializer):
description = SlideDataDescriptionSerializer(many=True, read_only=True, source='slidedatadescription_set')
class Meta:
model = SlideData
fields = ['catch', 'title', 'description', 'icon']
class SlideSerializer(serializers.ModelSerializer):
datas = SlideDataSerializer(many=True, read_only=True, source='slidedata_set')
class Meta:
model = Slide
fields = ['datas']
class PlanDataDescriptionSerializer(serializers.ModelSerializer):
class Meta:
model = PlanDataDescription
fields = ['description']
class PlanDataSerializer(serializers.ModelSerializer):
description = PlanDataDescriptionSerializer(many=True, read_only=True, source='plandatadescription_set')
class Meta:
model = PlanData
fields = ['stripColor', 'name', 'description', 'pricePerMonth', 'currency', 'picture']
class PlanSerializer(serializers.ModelSerializer):
datas = PlanDataSerializer(many=True, read_only=True, source='plandata_set')
class Meta:
model = Plan
fields = ['mainTitle', 'datas']
views.py
class ProjectList(generics.ListAPIView):
permission_classes = [permissions.AllowAny]
serializer_class_slide = SlideSerializer
serializer_class_plan = PlanSerializer
def get_queryset_object(self, Table, campaign, lang):
queryset = Table.objects.filter(campaign__name=campaign).filter(language__alpha2=lang)
return queryset[0]
def list(self, request):
Tables = [Slide,
Plan]
campaign = self.request.query_params.get('campaign') or "default"
lang = self.request.query_params.get('lang') or "en"
if not all(Table.objects.filter(campaign__name=campaign).filter(language__alpha2=lang) for Table in Tables):
campaign = "default"
if not all(Table.objects.filter(campaign__name=campaign).filter(language__alpha2=lang) for Table in Tables):
lang = "en"
slides = self.serializer_class_slide(self.get_queryset_object(Slide, campaign, lang))
plans = self.serializer_class_plan(self.get_queryset_object(Plan, campaign, lang))
return Response({
"slides": slides.data,
"plans": plans.data,
})
和 urls.py:
openapi_info = openapi.Info(
title="Projectname",
default_version="v1",
description="Endpoints",
terms_of_service="TBD",
contact=openapi.Contact(email="abc@123.com"),
license=openapi.License(name="BSD License"),
)
schema_view = get_schema_view(
openapi_info,
public=True,
permission_classes=(permissions.AllowAny,),
)
API_VERSION = 'v1'
urlpatterns = [
path('swagger/', schema_view.with_ui(
'swagger', cache_timeout=0), name='schema-swagger-ui'),
path('swagger/api.json', schema_view.without_ui( cache_timeout=0), name='schema-swagger-json'),
]
端点工作正常,但 swagger 没有创建正确的请求或响应,当我访问它时它给我这个错误消息:
view's ProjectList raised exception during schema generation; use `getattr(self, 'swagger_fake_view', False)` to detect and short-circuit this
Traceback (most recent call last):
File "/home/projects/env/lib/python3.8/site-packages/drf_yasg/inspectors/base.py", line 42, in call_view_method
return view_method()
File "/home/projects/env/lib/python3.8/site-packages/rest_framework/generics.py", line 108, in get_serializer
serializer_class = self.get_serializer_class()
File "/home/projects/env/lib/python3.8/site-packages/rest_framework/generics.py", line 122, in get_serializer_class
assert self.serializer_class is not None, (
AssertionError: 'ProjectList' should either include a `serializer_class` attribute, or override the `get_serializer_class()` method.
我不能包含一个序列化器 class 名称,因为我使用多个序列化器,我不能为此创建一个序列化器,因为它们被分成不同的模型。覆盖 get_serializer_class() 没有用,因为我也不知道如何将这些序列化器合并到那里。我怎样才能使这种表现形式发挥作用?提前致谢
这是因为您没有添加 class 的 Serializer 。您添加的那些序列化程序不是内置的。只需添加
serializer_class = SlideSerializer
到您的 class 变量,即使您不想使用它。如错误所述,您需要将 serializer_class 添加到您的 ListAPIView 。