Django 具有多个序列化程序的视图集上的DRF选项请求
我在我的视图集上使用了一个mixin,这样多个序列化程序可以跨不同的和任意的视图使用 我有一个名为Django 具有多个序列化程序的视图集上的DRF选项请求,django,django-rest-framework,Django,Django Rest Framework,我在我的视图集上使用了一个mixin,这样多个序列化程序可以跨不同的和任意的视图使用 我有一个名为invoice的额外操作,它只是一个普通的更新,但使用了不同的序列化程序。我需要在端点执行选项请求,以获取元素的选项。问题是,当我执行请求时,它从默认更新中提取序列化程序-ordersializer,而不是InvoiceSerializer。如何从正确的序列化程序中选择选项 class MultipleSerializerMixin: """ Mixin that allows fo
invoice
的额外操作,它只是一个普通的更新,但使用了不同的序列化程序。我需要在端点执行选项请求,以获取
元素的选项。问题是,当我执行请求时,它从默认更新中提取序列化程序-ordersializer
,而不是InvoiceSerializer
。如何从正确的序列化程序中选择选项
class MultipleSerializerMixin:
"""
Mixin that allows for multiple serializers based on the view's
`serializer_action_classes` attribute.
ex.
serializer_action_classes = {
'list': ReadOnlyListSerializer,
'retrieve': ReadOnlyDetailSerializer,
}
"""
def get_serializer_class(self):
try:
return self.serializer_action_classes[self.action]
except (KeyError, AttributeError):
return super().get_serializer_class()
class OrderAPIViewSet(MultipleSerializerMixin,
viewsets.ModelViewSet):
queryset = Order.objects.all()
serializer_class = serializers.OrderSerializer
serializer_action_classes = {
'invoice': serializers.InvoiceSerializer,
}
@action(detail=True, methods=['put'], url_name='invoice')
def invoice(self, request, *args, **kwargs):
"""
Invoice the order and order lines.
"""
return self.update(request, *args, **kwargs)
更新:
因此,在检查后,似乎在执行选项请求时,
view.action
是metadata
而不是invoice
,这解释了为什么序列化程序默认为view.serializer\u class
一种解决方法是创建一个可通过GET请求访问的发票,该请求手动将操作设置为发票
@action(detail=True, methods=['get', 'put'])
def invoice_schema(self, request, *args, **kwargs):
self.action = 'invoice'
data = self.metadata_class().determine_metadata(request, self)
return Response(data, status=status.HTTP_200_OK)
如果您有使用不同序列化程序的多个操作,则更简单的解决方案是覆盖视图的选项
方法,并从查询参数设置操作。这可以添加到MultipleSerializerMixin
中,使其成为使用此mixin的所有视图的默认行为
def options(self, request, *args, **kwargs):
self.action = request.query_params.get('action')
return super().options(request, *args, **kwargs)
Override
get\u serializer\u class
方法已足够,OPTIONS请求将检测要使用的序列化程序:
def get_serializer_class(self):
if self.request.method == 'GET':
return ReadOnlyShopSerializer
return ShopSerializer