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

时间:2015-11-01 05:26:59

标签: python django api 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)

我的CardSerializer序列化器是:

class CardSerializer(serializers.ModelSerializer):
    class Meta:
        model = Card

我如何

  • 如果视图集具有权限IsAuthenticated,则更改检索方法的序列化程序? 或者
  • 如果视图集有CardSerializer
  • ,请在IsAuthenticated添加字段

如果用户通过True / False

支持该卡,我可以返回SerializerMethodField

1 个答案:

答案 0 :(得分: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)
然后,

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

并将其他所有内容保留为默认的list / retrieve实施。

作为替代方案,您可以在序列化程序的__init__中添加该字段。您可以从context kwarg获取请求,执行相同的检查并添加您需要的任何字段。我认为,除了只有两个序列化器之外,它是不必要的复杂。