如何在Django中为用户模型添加自定义权限?

22 投票
5 回答
15252 浏览
提问于 2025-04-17 04:04

在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)

撰写回答