【问题标题】:How to add custom permission to the User model in django?如何在 django 中为 User 模型添加自定义权限?
【发布时间】:2011-12-05 04:09:19
【问题描述】:

默认情况下,在 django 中,当安装了 django.contrib.auth 运行 syncdb 时,它会在每个模型上创建默认权限...例如 foo.can_change 、 foo.can_delete 和 foo.can_add。要为模型添加自定义权限,可以在模型下添加类 Meta: 并在此处定义权限,如此处所述https://docs.djangoproject.com/en/dev/topics/auth/#custom-permissions

我的问题是,如果我想为 User 模型添加自定义权限,我应该怎么做?像 foo.can_view。我可以使用以下 sn-p 来做到这一点,

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 类。我应该只在类 Meta: 中拥有这些 UserProfile ,因为这是扩展用户模型的方式。但这是正确的方法吗?这不会将它与 UserProfile 模型联系起来吗?

【问题讨论】:

标签: python django django-permissions


【解决方案1】:

你可以这样做:

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

【讨论】:

  • 输入__init__.py 并连接到post_syncdb 可能是个好主意,但上面的代码对我不起作用。我必须使用ContentType.objects.get_for_model(model=auth_models.User)。否则,它起作用了。
  • post_syncdb 似乎不再是一个信号
【解决方案2】:

我认为这里没有“正确”的答案,但我使用的代码与您完全相同,只是我将 Permission.objects.create 更改为 Permission.objects.get_or_create 并且发现与 syncdb 同步

【讨论】:

  • 不会获取或创建,如果名称更改但代号保持不变,则创建另一个权限?
  • 你应该只使用代号作为get或create的get部分,并将名称放在“defaults”中
【解决方案3】:

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)

【讨论】:

  • 请问我必须将这段代码放在哪个文件中?我虽然要像早期版本的 Django 一样在模型中设置它,但我不确定......
  • @mcastle 我把它放在__init__.py 但“DoesNotExist:ContentType 匹配查询不存在”。错误仍在发生
  • 我不确定您的 sender 参数是否正确,它应该是一个应用实例,例如``` from django.apps import apps sender = apps.get_app_config('auth') ```
【解决方案4】:

这有点hacky,但还是在这里提到它以供参考。

我的网站有一个名为Setting 的通用模型,它存储了有关我希望某些用户能够编辑的网站的各种设置,而无需通过我的开发人员(如注册限制、地址或物品成本等)。

所有不能很好地映射到其他模型的权限(例如“向学生发送密码提醒电子邮件”、“生成付款核对报告”、“生成 PDF 收据”),这些权限实际上只与在管理区域,转储到这个Setting 模型上。

例如,这是模型:

class Setting(models.Model):
    name = models.CharField(max_length=50, unique=True)
    slug = models.SlugField(editable=False)
    description = models.TextField()
    value = models.TextField()
    class Meta:
        #for permissions that don't really relate to a particular model, and I don't want to programmatically create them.
        permissions = (
            ("password_reminder", "Send Password Reminder"),
            ("generate_payment_reconciliation_report", "Generate Payment Reconciliation Report"),
            ("generate_pdf_receipt", "Generate PDF Receipt"),
        )

这些设置是否都与Setting 模型严格相关?不,这就是为什么我说这有点骇人听闻。但很高兴我现在可以在这里转储所有这些权限,其余的将由 Django 的迁移命令处理。

【讨论】:

    猜你喜欢
    • 2013-09-09
    • 1970-01-01
    • 2017-05-27
    • 2010-12-17
    • 2013-02-27
    • 1970-01-01
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    相关资源
    最近更新 更多