django - 具有多个序列化器的 View 集上的 DRF 选项请求

标签 django django-rest-framework

我在 View 集上使用 mixin,以便可以在不同的 viewset actions 上使用多个序列化器和任何custom actions .

我有一个名为 invoice 的额外操作这只是一个正常的更新,但使用了不同的序列化器。我需要在端点执行 OPTIONS 请求以获取 <select> 的选项元素。问题是,当我执行请求时,它从默认更新中获取序列化器 - OrderSerializer而不是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)

更新:

检查 determine_actions method in metadata.SimpleMetadata 后似乎在执行 OPTIONS 请求 view.action 时是 metadata而不是invoice这解释了为什么序列化器默认为 view.serializer_class

最佳答案

一种解决方法是创建一个 extra action as a schema endpoint可以通过手动将操作设置为发票的 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)

如果您有多个使用不同序列化器的操作,则更干燥的解决方案是覆盖 View 的 options 方法并从查询参数设置操作。可以将其添加到 MultipleSerializerMixin 中,使其成为使用此 mixin 的所有 View 的默认行为。

def options(self, request, *args, **kwargs):
    self.action = request.query_params.get('action')
    return super().options(request, *args, **kwargs)

关于django - 具有多个序列化器的 View 集上的 DRF 选项请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60074411/

相关文章:

python - 如何对 WeekArchiveView 进行分页?

Django 使用未翻译的字符串而不是翻译

python - 多行 Charfield Django

django - 在 django rest 框架中更新 JSONField

django - 如何序列化多个模型对象?

python - 使用安全删除的用户进行 DRF 和 token 身份验证?

Django 自定义表单验证最佳实践?

python - Django 测试 - 如何使用 JSON 发送 HTTP Post Multipart

python - 在 Django Rest Framework 中正确更新嵌套序列化器

python - Django Rest Framework 多个数据库