好吧,首先,我已经阅读了有关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中删除某些字段。我在这里想念什么?