首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Pytest-django:设置用户权限

Pytest-django:设置用户权限
EN

Stack Overflow用户
提问于 2017-02-14 07:32:25
回答 2查看 2.4K关注 0票数 3

我使用pytest 3.0.6和pytest-django 3.1.2为Django开发了一个库。我有一个非常简单的测试失败,我不明白会发生什么:

代码语言:javascript
复制
# test_mytest.py
import pytest
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType


@pytest.mark.django_db
def test_user_has_perm(django_user_model):
    # Create a new user
    john_doe = django_user_model.objects.create_user('johndoe', email='jd@example.com', password='123456')

    # Get or create the permission to set on user
    user_ct = ContentType.objects.get(app_label='auth', model='user')
    p, _ = Permission.objects.get_or_create(content_type=user_ct, codename='delete_user', name="Can delete user")

    # User don't have the permission
    assert john_doe.has_perm(p) is False

    # Set permission to user
    john_doe.user_permissions.add(p)
    assert john_doe.has_perm(p) is True  # ---> FAIL

以防万一,测试结果是:

代码语言:javascript
复制
$ pytest
============================= test session starts =============================
platform win32 -- Python 3.5.3, pytest-3.0.6, py-1.4.32, pluggy-0.4.0
Django settings: testsite.settings (from ini file)
rootdir: D:\Dev\foss\django-modern-rpc, inifile: tox.ini
plugins: pythonpath-0.7.1, django-3.1.2, cov-2.4.0
collected 1 items

modernrpc\tests\test_test_test.py F

================================== FAILURES ===================================
_____________________________ test_user_has_perm ______________________________

django_user_model = <class 'django.contrib.auth.models.User'>

    @pytest.mark.django_db
    def test_user_has_perm(django_user_model):
        # Create a new user
        john_doe = django_user_model.objects.create_user('johndoe', email='jd@example.com', password='123456')

        # Get or create the permission to set on user
        user_ct = ContentType.objects.get(app_label='auth', model='user')
        p, _ = Permission.objects.get_or_create(content_type=user_ct, codename='delete_user', name="Can delete user")

        # User don't have the permission
        assert john_doe.has_perm(p) is False

        # Set permission to user
        john_doe.user_permissions.add(p)
>       assert john_doe.has_perm(p) is True  # ---> FAIL
E       assert False is True
E        +  where False = <bound method PermissionsMixin.has_perm of <User: johndoe>>(<Permission: auth | user | Can delete user>)
E        +    where <bound method PermissionsMixin.has_perm of <User: johndoe>> = <User: johndoe>.has_perm

modernrpc\tests\test_test_test.py:20: AssertionError
========================== 1 failed in 0.32 seconds ===========================

配置块,来自tox.ini:

代码语言:javascript
复制
[pytest]
DJANGO_SETTINGS_MODULE = testsite.settings
norecursedirs = .git __pycache__ build dist venv* .tox .vscode .cache *.egg-info
python_paths = modernrpc/tests
testpaths = modernrpc/tests
python_files = test_*.py dummy_*.py

以及来自测试设置的DB配置:

代码语言:javascript
复制
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'modern_rpc.sqlite3'),
    },
}

我做错什么了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-02-17 09:35:10

您需要使用字符串'app_label.codename'

如果用户具有指定的权限,则返回True,其中perm格式为“”。

此外,如果自上次调用user._perm_cache或从数据库检索该用户的新实例以来更改了权限,则必须清除user._user_perm_cachehas_perm,以确保没有缓存:

代码语言:javascript
复制
 del john_doe._perm_cache
 del john_doe._user_perm_cache 
 # OR
 john_doe = django_user_model.objects.get(username='johndoe')

这是因为has_perm将调用auth后端,后者将首先查询这些缓存。

票数 6
EN

Stack Overflow用户

发布于 2017-02-17 09:15:12

来自文档

has_perm(perm,obj=None) 如果用户具有指定的权限,则返回True,其中perm为格式 "<app label>.<permission codename>"。 (请参阅权限文档)。如果用户不活动,此方法将始终返回False。 如果传入obj,此方法将不检查模型的权限,而是检查此特定对象的权限。

因此,此方法接受字符串而不是权限对象。

john_doe.has_perm('auth.delete_user')

应该返回True。( delete_user权限分配了auth应用程序,因为您使用了user_ct来创建它,user_ct的应用程序就是auth)。

但是,在您的示例中,这种情况不会立即发生,因为也有一个权限检查缓存

在您重新获取对象之后,它将工作。

代码语言:javascript
复制
#Be aware this only works after Django 1.9+
#https://code.djangoproject.com/ticket/26514
john_doe.refresh_from_db()
#Otherwise use:
john_doe = User.objects.get(pk=john_doe.pk)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42220272

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档