如何根据已登录的用户撤销Django Rest Framework序列化程序中的特定属性?

问题描述 投票:0回答:1

我有一个Django Rest Framework API,在该API中,我只允许登录用户POST新项目。 ViewSet如下所示:

class APIAuthGroup(InAuthGroup):
    """
    A permission to only allow WRITE/POST access if and only if a user is logged in,
    and is a member of the SA role inside keycloak.
    """
    allowed_group_names = [settings.KEYCLOAK_SA_WRITE_PERMISSION]

    def has_permission(self, request, view):
        return request.method in SAFE_METHODS \
               or super(APIAuthGroup, self).has_permission(request, view)


class DevicesViewSet(DatapuntViewSetWritable):
    """
    A view that will return the devices and makes it possible to post new ones
    if the user is logged in
    """

    queryset = Device.objects.all().order_by('id')

    serializer_class = DeviceSerializer
    serializer_detail_class = DeviceSerializer

    http_method_names = ['post', 'list', 'get']

    permission_classes = [APIAuthGroup]

还有我的序列化器:

class PersonSerializer(HALSerializer):
    name = serializers.CharField(required=True, allow_blank=False, max_length=255)
    email = serializers.EmailField()
    organisation = serializers.CharField(required=False, allow_blank=True, max_length=250)

    class Meta:
        model = Person
        fields = ('name', 'email', 'organisation')


class DeviceSerializer(HALSerializer):
    long = serializers.SerializerMethodField()
    lat = serializers.SerializerMethodField()
    organisation = serializers.SerializerMethodField()
    owner = PersonSerializer()
    contact = PersonSerializer(required=False)

    class Meta:
        model = Device
        fields = (
            '_links',
            'id',
            'frequency',
            'longitude',
            'latitude',
            'organisation',
            'owner',
            'contact'
        )

    def get_organisation(self, obj):
        if obj.owner:
            return obj.owner.organisation
        return 'Onbekend'

我现在只希望在用户登录并且登录的用户电子邮件地址等于owner的情况下返回contactowner.email

尽管我不确定如何以及在何处能够做到这一点。我应该在序列化程序还是在视图集中执行此操作?如何?

欢迎所有提示!

python django django-rest-framework authorization
1个回答
0
投票

您可以覆盖序列化程序的to_representation方法:

class DeviceSerializer(HALSerializer):
    long = serializers.SerializerMethodField()
    lat = serializers.SerializerMethodField()
    organisation = serializers.SerializerMethodField()
    owner = PersonSerializer()
    contact = PersonSerializer(required=False)

    class Meta:
        model = Device
        fields = (
            '_links',
            'id',
            'frequency',
            'longitude',
            'latitude',
            'organisation',
            'owner',
            'contact'
        )

    def get_organisation(self, obj):
        if obj.owner:
            return obj.owner.organisation
        return 'Onbekend'

    def to_representation(self, instance):
        data = super().to_representation(instance)
        if obj.owner != self.context["request"].user:
            data.pop("owner")
            data.pop("contact")
        return data 
© www.soinside.com 2019 - 2024. All rights reserved.