【问题标题】:Django 1.7 - Adding permissions programmatically does not work as expectedDjango 1.7 - 以编程方式添加权限无法按预期工作
【发布时间】:2015-03-11 16:55:19
【问题描述】:

这里发生了什么?

> 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 permissions django-1.7


    【解决方案1】:

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

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

    【讨论】:

    • 我希望我们现在可以使用user.refresh_from_db()
    • 不,refresh_from_db 不会清除缓存。在the docs的评论中提到了
    • 添加了额外的模型权限,不会反映在测试数据库上。我设法通过 python manage.py update 权限更新了原始数据库,但是在我测试时它不应该得到反映。这个答案在这种情况下会有所帮助吗?
    • 不,这听起来与这个问题/答案无关。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      我相信用户实例具有第一次从数据库中提取时填充的权限缓存。在调用has_perm之前尝试删除缓存:

      delattr(user, '_perm_cache')
      

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

      【讨论】:

      • 想知道为什么 django 没有内置的清除对象缓存的方法。这是一个非常常见的用例(添加权限并执行操作...)。
      猜你喜欢
      • 2017-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-09
      相关资源
      最近更新 更多