Django 1.7 - 以编程方式添加权限无法按预期工作

Django 1.7 - Adding permissions programmatically does not work as expected

这是怎么回事?

> from django.contrib.auth.models import Permission
> from django.contrib.contenttypes.models import ContentType
> p = Permission.objects.filter(
    content_type = ContentType.objects.get_for_model(Transaction)
).get(
    codename = 'add_transaction'
)
> user.user_permissions.add(p)

> user.user_permissions.all()
[<Permission: myapp | Transaction | Can add Transaction>]
> user.get_all_permissions()
set([])
> user.has_perm('add_transaction')
False
> user.has_perm('myapp.add_transaction')
False

我是不是遗漏了什么地方的存档?

我相信用户实例有一个权限缓存,当它第一次从数据库中被拉出时就会被填充。在调用 has_perm 之前尝试删除缓存:

delattr(user, '_perm_cache')

之后,has_perm 应该会按预期工作。通常这不是问题,因为您很少添加然后立即测试同一用户实例的权限(无需再次将其从数据库中拉出)。不过,当您在 python shell 中进行测试时,肯定会绊倒您。

ModelBackend缓存用户对象的权限。 Django docs 建议您在更改权限后从数据库重新加载用户。

user.user_permissions.add(p)
user = User.objects.get(pk=user.pk)

dgel的回答正确但不完整。 _perm_cache_user_perm_cache 都需要清除才能强制重新加载。

for attr in ('_perm_cache', '_user_perm_cache'):
    delattr(user, attr)