如何处理字段级权限并仅从序列化程序返回允许的字段?

时间:2019-07-17 11:08:58

标签: django serialization django-rest-framework permissions

好吧,首先,我已经阅读了有关DRF权限的文档,所有在SO和Google-land中都找到的匹配项。

我试图仅返回用户可以根据字段级权限查看的字段。我已经看到了如何在__init__方法中动态修改序列化程序的“ fields”属性的示例,这似乎是执行所需操作的最佳位置。但是在获取当前用户的权限的过程中,如果用户无效或完全没有权限,我需要提出一个例外。

问题是即使请求不是__init__代码所针对的端点,__init__似乎在请求期间正在执行。

这是我的序列化器:

class ClientSerializer(AddressPhoneSerializerMixin, serializers.ModelSerializer):

    url = serializers.HyperlinkedIdentityField(view_name="clients:client-detail")
    contacts = ClientContactsSerializer(many=True, read_only=True)
    projects = ClientProjectsSerializer(many=True, read_only=True)
    project_users = ClientProjectUsersSerializer(many=True, read_only=True)

    class Meta:
        model = Client
        fields = (
            'url',
            'id',
            'name',
            'slug',
            'status',
            'address',
            'country',
            'phone_number',
            'mobile_number',
            'fax_number',
            'created',
            'updated',
            'deleted',
            'contacts',
            'projects',
            'project_users',
        )

    def __init__(self, *args, **kwargs):
        super(ClientSerializer, self).__init__(*args, **kwargs)
        self.check_permissions()

    def check_permissions(self):
        permissions = None

        request = self.context.get("request")
        if request and hasattr(request, "user"):
            user = request.user
            permissions = UserPermissionsList(user.id)

        if not permissions or permissions is None:
            raise PermissionDenied('You do not have permission to view clients.')

        for field_name in self.fields:
            if not user.has_perm('clients.view_%s' % field_name):
                self.fields.pop(field_name)

当我仅加载站点的根目录:example.com/(而不是客户端列表:example.com/clients/)时,出现异常(“您无权查看客户端。”)。因此,似乎代码可以在 any 页面加载中运行,而不仅仅是在访问客户端时。是因为URLSconf导入了Client模型,而Client模型又导入了序列化程序?如果是这样,为什么在不访问客户端时实例化序列化程序?

我知道对象级权限通常被降级为视图,但是如果我将字段级权限放在那里,我看不到如何从返回的序列化JSON中删除某些字段。我在这里想念什么?

0 个答案:

没有答案