如何在Django中为用户模型添加自定义权限?
在Django中,当你运行syncdb命令并且安装了django.contrib.auth时,它会自动为每个模型创建一些默认的权限,比如foo.can_change、foo.can_delete和foo.can_add。如果你想给模型添加自定义权限,可以在模型下面加上一个叫做Meta的类,然后在里面定义权限,具体的做法可以参考这里 https://docs.djangoproject.com/en/4.1/topics/auth/customizing/#custom-permissions
我想问的是,如果我想给用户模型添加一个自定义权限,比如foo.can_view,我可以用下面的代码来实现,
ct = ContentType.objects.get(app_label='auth', model='user')
perm = Permission.objects.create(codename='can_view', name='Can View Users',
content_type=ct)
perm.save()
但是我希望这个自定义权限能和syncdb很好地配合,比如在我自定义模型下的Meta类里。那我是不是应该把这些放在UserProfile的Meta类里,因为这是扩展用户模型的方式。但这样做是对的吗?这样做会不会把它和UserProfile模型绑定在一起?
5 个回答
2
这是针对Django 1.8的更新回答。这里提到的信号pre_migrate
是用来替代pre_syncdb
的,因为syncdb已经不再推荐使用,文档建议如果信号会改变数据库,就应该使用pre_migrate
而不是post_migrate
。另外,@receiver
被用来将add_user_permissions
连接到这个信号上。
from django.db.models.signals import pre_migrate
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth import models as auth_models
from django.contrib.auth.models import Permission
from django.conf import settings
from django.dispatch import receiver
# custom user related permissions
@receiver(pre_migrate, sender=auth_models)
def add_user_permissions(sender, **kwargs):
content_type = ContentType.objects.get_for_model(settings.AUTH_USER_MODEL)
Permission.objects.get_or_create(codename='view_user', name='View user', content_type=content_type)
5
我觉得这里没有一个“正确”的答案,不过我用了和你完全一样的代码,只是把 Permission.objects.create
改成了 Permission.objects.get_or_create
,这样就能顺利和 syncdb 同步了。
9
你可以这样做:
在你的Django应用的 __init__.py
文件中添加:
from django.db.models.signals import post_syncdb
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth import models as auth_models
from django.contrib.auth.models import Permission
# custom user related permissions
def add_user_permissions(sender, **kwargs):
ct = ContentType.objects.get(app_label='auth', model='user')
perm, created = Permission.objects.get_or_create(codename='can_view', name='Can View Users', content_type=ct)
post_syncdb.connect(add_user_permissions, sender=auth_models)