在Django中添加新的自定义权限


71

我在我的Django模型中使用自定义权限,如下所示:

class T21Turma(models.Model):
    class Meta:
        permissions = (("can_view_boletim", "Can view boletim"),
                       ("can_view_mensalidades", "Can view mensalidades"),)

问题是,当我向列表添加权限auth_permission时,运行syncdb时不会将其添加到表中。我究竟做错了什么。如果有什么不同,我正在使用south进行数据库迁移。


您可以在“权限”模型中固定字段长度: stackoverflow.com/a/28343007/3310666
缺少分号

Answers:


60

南方不跟踪django.contrib.auth权限。有关更多信息,请参见故障单#211

票证上的评论之一表明,--all在syncdb上使用该选项可以解决问题。


1
听起来确实是我的问题,除了我无法使--all开关与syncdb一起使用,或者找不到在任何地方记录的开关。
gerdemb

5
在我之前升级到南部0.6.2(我正在运行0.5)之后,此方法起作用。
gerdemb

这只是给我一个错误“ DatabaseError:对于类型字符变化(50)而言,值太长”
Cerin 2013年

这意味着您数据库中已有一个超过50个字符的值。
caesarsol

@Cerin-当我的权限描述超过50个字符时,我明白了。似乎有可能犯该错误。
罗伯·格兰特

48

如果要“ manage.py migration”做所有事情(不调用syncdb --all)。您需要通过迁移创建新的权限:

user@host> manage.py datamigration myapp add_perm_foo --freeze=contenttypes --freeze=auth

编辑创建的文件:

class Migration(DataMigration):

    def forwards(self, orm):
        "Write your forwards methods here."
        ct, created = orm['contenttypes.ContentType'].objects.get_or_create(
            model='mymodel', app_label='myapp') # model must be lowercase!
        perm, created = orm['auth.permission'].objects.get_or_create(
            content_type=ct, codename='mymodel_foo', defaults=dict(name=u'Verbose Name'))

2
不需要最后三行,可以使用defaults关键字参数ofget_or_create代替链接
Ivan Virabyan 2011年

5
如果使用此方法,则需要将选项添加--freeze=contenttypes --freeze=auth到datamigration命令。否则,您将在下面收到错误@balmaster提及。例如:manage.py datamigration myapp add_perm_foo --freeze=contenttypes --freeze=auth
calebbrown 2011年

27

这对我有用:

./manage.py update_permissions

这是一个django扩展名的东西。


1
“ DatabaseError:对于类型字符变化(50),值太长”。原因是我的权限名太长,但这是一条非常无用的错误消息,尤其是当我添加数十个新权限时。
Cerin

20

您可以连接到post_migrate信号,以便在迁移后更新权限。我使用以下代码,从带有Devion的Dev稍作修改,最初从django-extensions修改

# Add to your project-level __init__.py

from south.signals import post_migrate

def update_permissions_after_migration(app,**kwargs):
    """
    Update app permission just after every migration.
    This is based on app django_extensions update_permissions management command.
    """
    from django.conf import settings
    from django.db.models import get_app, get_models
    from django.contrib.auth.management import create_permissions

    create_permissions(get_app(app), get_models(), 2 if settings.DEBUG else 0)

post_migrate.connect(update_permissions_after_migration)

1
在使用Gunicorn之类的东西来运行应用程序时会遇到问题,即它无法找到wsgi.py文件中设置的环境变量。
Pier1 Sys

2

当我使用以下代码运行迁移时

ct, created = orm['contenttypes.ContentType'].objects.get_or_create(model='mymodel',     app_label='myapp') # model must bei lowercase!
perm, created = orm['auth.permission'].objects.get_or_create(content_type=ct, codename='mymodel_foo')

我越来越喜欢错误

File "C:\Python26\lib\site-packages\south-0.7.3-py2.6.egg\south\orm.py", line 170, in  __getitem__
raise KeyError("The model '%s' from the app '%s' is not available in this migration." % (model, app))
KeyError: "The model 'contenttype' from the app 'contenttypes' is not available in this migration."

为防止此错误,我修改了代码

from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import Permission

class Migration(DataMigration):

    def forwards(self, orm):
        "Write your forwards methods here."
        ct = ContentType.objects.get(model='mymodel', app_label='myapp') 
        perm, created = Permission.objects.get_or_create(content_type=ct, codename='mymodel_foo')
        if created:
            perm.name=u'my permission description'
            perm.save()

7
馊主意; 您应该使用冻结的ORM。添加--freeze=contenttypes --freeze=auth到您的./manage.py datamigration命令行。
Vebjorn Ljosa
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.