更新时间:2023-12-01 13:15:52
即使使用标准的 auth.User
模型。但是基础是Django的 PermissionsMixin
定义了 has_perm
方法,它接受一个模型实例。 Django默认情况下不做任何事情,但您可以。
has_perm
方法有效地将艰苦的工作传递到注册认证后端。因此,您可以创建专门用于执行对象级权限检查的自定义身份验证后端。它不需要真正处理身份验证。它可以像基本类上的单一方法一样简单。所有你需要的东西如下(未经测试):
class ObjectPermissionsBackend(object):
def has_perm(self,user_obj,perm,obj = None):
如果不是obj:
return False#不处理非对象权限
如果perm =='查看':
返回True#任何人都可以查看
elif obj.author_id == user_obj.pk:
return True
else:
return False
告诉Django使用 AUTHENTICATION_BACKENDS
设置使用您的自定义后端。在settings.py:
AUTHENTICATION_BACKENDS =('django.contrib.auth.backends.ModelBackend','path.to.ObjectPermissionsBackend ')
然后,在你的代码中:
如果user.has_perm('edit',article_instance):
#允许编辑
请参阅 https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#custom-users-and-permissions 和 https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#specifying-authentication-backends
I have implemented my own User model class as follows. Note that is it NOT customizing django's auth.User
model. I am new to this object permission knowledge and especially in this self-defined User model which is required in my project.
Could you give an example of adding per-object permission in this case? Much appreciated.
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
class CustomUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(max_length=40, unique=True)
//.... other fields are omitted
class Article(models.Model):
title = models.CharField('title', max_length=120)
body = models.TextField('body')
author = models.ForeignKey(CustomUser)
Now, the object permission comes into play. Each user can create/update/delete/view their own article objects, but ONLY view others' articles without the permission to update/delete them.
From the django docs, the Model level permission does not apply here. If the Article is given model level update permission, then all users can update others' Article.
So, I found out the django-guardian. However, there seems to be no hope for this self-defined CustomUser model, as it relies heavily on Django's auth.User
model!
https://django-guardian.readthedocs.org/en/v1.2/userguide/custom-user-model.html
UPDATE:
Object-level permissions are not built into Django, even when using the standard auth.User
model. But the foundation is there in that Django's PermissionsMixin
defines the has_perm
method, which accepts a model instance. Django does nothing with it by default, but you can.
The has_perm
method effectively passes the hard work off onto the registered authentication backends. So you can create a custom authentication backend specifically for performing your object-level permission checks. It does not need to actually handle authentication. It can be as simple as a single method on a basic class. Something like the following (untested) is all you should need:
class ObjectPermissionsBackend(object):
def has_perm(self, user_obj, perm, obj=None):
if not obj:
return False # not dealing with non-object permissions
if perm == 'view':
return True # anyone can view
elif obj.author_id == user_obj.pk:
return True
else:
return False
Tell Django to use your custom backend using the AUTHENTICATION_BACKENDS
setting. In settings.py:
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend', 'path.to.ObjectPermissionsBackend')
Then, in your code:
if user.has_perm('edit', article_instance):
# allow editing
See https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#custom-users-and-permissions and https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#specifying-authentication-backends