首页 > 解决方案 > DRF:如何根据实例属性使序列化器字段不同

问题描述

我对 DRF 或 Django 并不太熟悉,但这里有:

我正在开发一个返回用户的锻炼 API,并且用户能够设置其个人资料的可见性。该表看起来像:

id | username | email | coach_id | visibility

, ,visibility中的一个在哪里。publiccoachprivate

这意味着如果User 1has visibility = private,另一个获取他们的个人资料的用户应该只看到属性idusername,但用户自己应该得到所有属性。

visibility = public如果或,用户的教练应该会看到个人资料visibility = coach

我已经研究过动态设置序列化程序的fields- 变量,但没有运气(因为应该根据对象/实例的内容“生成”字段)。

我也研究过extra_field = serializers.SerializerMethodField(),但这导致所有值都显示为 的子属性extra_field

我想知道的是:解决这个问题的最佳方法是什么?

标签: djangodjango-rest-framework

解决方案


我解决了!

我在我的序列化程序中使用了to_representation-function,如下所示:

class VisibilityAwareUserSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = get_user_model()
        fields = [
            "id",
            "username",
            "visibility",
            "email",
            "coach",
        ]

    def to_representation(self, instance):
        ret = super(PermissionAwareUserSerializer, self).to_representation(instance)
        fields_to_pop = [
            "email",
            "coach",
        ]
        if not self.userCanSeeObject(self.context['request'].user, instance):
            [ret.pop(field,'') for field in fields_to_pop]
        return ret

    def userCanSeeObject(self, user, obj):
        return ((obj.visibility == "public") or (obj.visibility == "coach" and obj.coach == user or obj == user) or (obj.visibility == "private" and obj == user))

随意指出此解决方案中的弱点,但它似乎对我很有效。


推荐阅读