我正在使用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
观点:
class UserListAPIView(ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (permissions.DjangoModelPermissions,)
设定:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissions'
]
}
问题在于,我实施的UserListAPIView
成功地向不属于Group
且没有任何自定义User Permission
的用户返回了所有对象的列表。在我看来DjangoModelPermissions
没有任何效果。
答案 0 :(得分:3)
class CustomDjangoModelPermission(permissions.DjangoModelPermissions):
def __init__(self):
self.perms_map['GET'] = ['%(app_label)s.view_%(model_name)s']
答案 1 :(得分:2)
@Yannic Hamann的解决方案有一个小错误。它会覆盖父母的perms_map ['GET']。
如下所示,字典覆盖需要深度复制。
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']
字典覆盖测试
class Parent:
perms = {'GET':'I am a Parent !'}
class Child(Parent):
def __init__(self):
self.perms['GET'] = 'I am a Child !'
词典覆盖结果
>>> 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.
^^^^^
答案 2 :(得分:0)
您必须覆盖客户DjangoModelPermissions。
class BaseModelPerm(permissions.DjangoModelPermissions):
def get_custom_perms(self, method, view):
app_name = view.model._meta.app_label
return [app_name+"."+perms for perms in view.extra_perms_map.get(method, [])]
def has_permission(self, request, view):
perms = self.get_required_permissions(request.method, view.model)
perms.extend(self.get_custom_perms(request.method, view))
return (
request.user and
(request.user.is_authenticated() or not self.authenticated_users_only) and
request.user.has_perms(perms)
)
您可以在视图中使用,如下所示
class ViewName(generic.ListApiView):
""" Trip listing view """
model = model_name
serializer_class = serializer_class
permission_classes = (permissions.IsAuthenticated,BaseModelPerm)
queryset = model.objects.all()
extra_perms_map = {
'GET': ["can_view_trip"],
}
添加您要添加的任何额外权限。