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

Django 1.7-以编程方式添加权限无法按预期工作,django,permissions,django-1.7,Django,Permissions,Django 1.7,这是怎么回事 > 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 =

这是怎么回事

> 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
>来自django.contrib.auth.models的导入权限
>从django.contrib.contenttypes.models导入ContentType
>p=Permission.objects.filter(
content\u type=ContentType.objects.get\u for\u模型(事务)
).得到(
代码名='add_transaction'
)
>user.user\u permissions.add(p)
>user.user\u权限.all()
[]
>user.get_all_权限()
集合([])
>user.has\u perm('add\u transaction'))
假的
>user.has\u perm('myapp.add\u transaction'))
假的

我是否丢失了此处的某个存储?

我相信用户实例有一个权限缓存,当它第一次从数据库中取出时,会填充该缓存。在调用
has\u perm
之前,请尝试删除缓存:

delattr(user, '_perm_cache')

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

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

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

dgel的回答是正确的,但不完整。需要清除
\u perm\u缓存
\u user\u perm\u缓存
,以强制完全重新加载

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

想知道为什么django没有清除对象缓存的内置方式。这是一个非常简单的用例(添加权限并执行操作…)。我希望我们现在可以使用
user.refresh\u from\u db()
。不,
refresh\u from\u db
不会清除缓存。在添加的额外模型权限中的注释中提到了这一点,该权限未反映在测试数据库中。我设法通过python manage.py update权限更新了原始数据库,但在测试时它不应该被反映出来。。这个答案在这种情况下有用吗?不,这听起来与这个问题/答案无关。