Django Rest Framework:根据身份验证更改序列化程序或添加字段

blu*_*inc 2 python api django django-rest-framework

我有一个视图集如下:

class CardViewSet(viewsets.ReadOnlyModelViewSet):
    """
    Standard Viewset for listing cards
    """
    pagination_class = StandardCellSetPagination
    permission_classes = [AllowAny, IsAuthenticated]

    def list(self, request):
        queryset = Card.objects.exclude(reply_to__isnull=False).order_by('-created')
        cards = self.paginate_queryset(queryset)
        serializer = CardCellSerializer(cards, many=True)
        return self.get_paginated_response(serializer.data)

    def retrieve(self, request, pk=None):
        queryset = Card.objects.all()
        card = get_object_or_404(queryset, pk=pk)
        serializer = CardSerializer(card)
        return Response(serializer.data)
Run Code Online (Sandbox Code Playgroud)

我的CardSerializer序列化器是:

class CardSerializer(serializers.ModelSerializer):
    class Meta:
        model = Card
Run Code Online (Sandbox Code Playgroud)

我该怎么做

  • 如果视图集具有权限,则更改检索方法的序列化程序IsAuthenticated?要么
  • CardSerializerif视图集中添加一个字段IsAuthenticated

True / False如果用户通过a收藏了卡,我可以返回SerializerMethodField

Iva*_*van 6

你可以这样做:

def retrieve(self, request, pk=None):
    queryset = Card.objects.all()
    card = get_object_or_404(queryset, pk=pk)

    # Same for list method
    if request.user and request.user.is_authenticated:
        serializer = AuthenticatedCardSerializer(card)
    else:
        serializer = CardSerializer(card)

    return Response(serializer.data)
Run Code Online (Sandbox Code Playgroud)

AuthenticatedCardSerializer然后可以扩展CardSerializer以包括经过身份验证的用户可见的任何字段.

此外,如果你决定使用相同的序列化行为listretrieve,你可以覆盖get_serializer_class在你的视图集中,而不是:

def get_serializer_class(self):
    if self.request.user and self.request.user.is_authenticated:
        return AuthenticatedCardSerializer
    else:
        return CardSerializer
Run Code Online (Sandbox Code Playgroud)

并将其他所有内容保留为默认list/ retrieve实现.

作为替代方案,您可以在序列化程序中添加该字段__init__.您可以从contextkwarg 获取请求,执行相同的检查并添加您需要的任何字段.我认为它不仅仅比拥有两个序列化器更复杂.