Yan*_*ann 3 python django django-rest-framework
我正在玩djangorestframework,我的目标是在DjangoModelPermissions对GET请求做出反应的视图上使用。官方文件说:
也可以覆盖默认行为以支持自定义模型权限。例如,您可能要包括请求的
view模型权限GET。
因此,我如下修改了我的模型:
class User(AbstractUser):
display_name = models.CharField(_('Display Name'), blank=True, max_length=255)
class Meta:
permissions = (
("view_user", "Can view users"),
)
def __str__(self):
return self.username
Run Code Online (Sandbox Code Playgroud)
和视图:
class UserListAPIView(ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (permissions.DjangoModelPermissions,)
Run Code Online (Sandbox Code Playgroud)
设定:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissions'
]
}
Run Code Online (Sandbox Code Playgroud)
问题是我的实现UserListAPIView成功地将所有对象的列表返回给不属于Group自定义对象的用户User Permission。在我看来,这DjangoModelPermissions没有效果。
@Yannic Hamann 的解决方案有一个小错误。它会覆盖父级的 perms_map['GET']。
如下,A 字典覆盖需要 deepcopy。
class CustomDjangoModelPermission(permissions.DjangoModelPermissions):
def __init__(self):
self.perms_map = copy.deepcopy(self.perms_map) # you need deepcopy when you inherit a dictionary type
self.perms_map['GET'] = ['%(app_label)s.view_%(model_name)s']
Run Code Online (Sandbox Code Playgroud)
字典覆盖测试
class Parent:
perms = {'GET':'I am a Parent !'}
class Child(Parent):
def __init__(self):
self.perms['GET'] = 'I am a Child !'
Run Code Online (Sandbox Code Playgroud)
字典覆盖结果
>>> print(Parent().perms['GET'])
I am a Parent !
>>> print(Child().perms['GET'])
I am a Child !
>>> print(Parent().perms['GET'])
I am a Child ! # Parent's perms is overwritten by Child.
^^^^^
Run Code Online (Sandbox Code Playgroud)
哎呀,这比我想象的要容易:
class CustomDjangoModelPermission(permissions.DjangoModelPermissions):
def __init__(self):
self.perms_map['GET'] = ['%(app_label)s.view_%(model_name)s']
Run Code Online (Sandbox Code Playgroud)