我可以在Django设置中定义类,如何在测试中覆盖此类设置? [英] Can I define classes in Django settings, and how can I override such settings in tests?

查看:92
本文介绍了我可以在Django设置中定义类,如何在测试中覆盖此类设置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们将Django用于 Speedy Net和Speedy Match (当前为Django 1.11. 17,由于我们的要求之一(django-modeltranslation),我们无法升级到较新版本的Django.我想将某些设置定义为类.例如:

We are using Django for Speedy Net and Speedy Match (currently Django 1.11.17, we can't upgrade to a newer version of Django because of one of our requirements, django-modeltranslation). I want to define some of our settings as classes. For example:

class UserSettings(object):
    MIN_USERNAME_LENGTH = 6
    MAX_USERNAME_LENGTH = 40

    MIN_SLUG_LENGTH = 6
    MAX_SLUG_LENGTH = 200

    # Users can register from age 0 to 180, but can't be kept on the site after age 250.
    MIN_AGE_ALLOWED_IN_MODEL = 0  # In years.
    MAX_AGE_ALLOWED_IN_MODEL = 250  # In years.

    MIN_AGE_ALLOWED_IN_FORMS = 0  # In years.
    MAX_AGE_ALLOWED_IN_FORMS = 180  # In years.

    MIN_PASSWORD_LENGTH = 8
    MAX_PASSWORD_LENGTH = 120

    PASSWORD_VALIDATORS = [
        {
            'NAME': 'speedy.core.accounts.validators.PasswordMinLengthValidator',
        },
        {
            'NAME': 'speedy.core.accounts.validators.PasswordMaxLengthValidator',
        },
    ]

(在中定义https://github.com/speedy-net/speedy-net/blob/staging/speedy/net/settings/global_settings.py ).然后在模型中,我尝试使用:

(which is defined in https://github.com/speedy-net/speedy-net/blob/staging/speedy/net/settings/global_settings.py). And then in the models, I tried to use:

from django.conf import settings as django_settings

class User(ValidateUserPasswordMixin, PermissionsMixin, Entity, AbstractBaseUser):
    settings = django_settings.UserSettings

(然后在类中使用settings的属性,例如settings.MIN_USERNAME_LENGTH).

(and then use attributes of settings, such as settings.MIN_USERNAME_LENGTH, in the class).

但是会引发异常

AttributeError: 'Settings' object has no attribute 'UserSettings'

(但是如果我在那里使用不是类的常量,它不会引发异常).

(but it doesn't throw an exception if I use there a constant which is not a class).

这是第一个问题.同时,我改为定义:

This is the first problem. In the meantime, I defined instead:

from speedy.net.settings import global_settings as speedy_net_global_settings

class User(ValidateUserPasswordMixin, PermissionsMixin, Entity, AbstractBaseUser):
    settings = speedy_net_global_settings.UserSettings

第二个问题是,如何在测试中覆盖此类设置?例如,我使用以下代码:

The second problem, is how do I override such settings in tests? For example, I use the following code:

from speedy.core.settings import tests as tests_settings

@override_settings(MAX_NUMBER_OF_FRIENDS_ALLOWED=tests_settings.OVERRIDE_MAX_NUMBER_OF_FRIENDS_ALLOWED)

https:中: //github.com/speedy-net/speedy-net/blob/staging/speedy/core/friends/tests/test_views.py .但是,如果要在类UserSettings中定义MAX_NUMBER_OF_FRIENDS_ALLOWED,该如何覆盖它?

in https://github.com/speedy-net/speedy-net/blob/staging/speedy/core/friends/tests/test_views.py. But if MAX_NUMBER_OF_FRIENDS_ALLOWED would be defined in the class UserSettings, how do I override it?

推荐答案

感谢@Blender提供提示:

Thanks to @Blender for the tip:

Django的设置对象明确跳过了您的所有对象 包含非大写名称的设置模块.如果您将班级重命名为 USER_SETTINGS,它将正常工作.

Django's settings object explicitly skips over any objects in your settings module with non-uppercase names. If you rename your class to USER_SETTINGS, it will work.

我不知道所有设置都必须是大写的.因此,我将class UserSettings重命名为class USER_SETTINGS(尽管PyCharm不喜欢它),但是我检查了一下,还可以在文件末尾添加以下代码:

I was not aware that all the settings have to be uppercase. So I renamed class UserSettings to class USER_SETTINGS (although PyCharm doesn't like it), but I checked and it's also possible to add this code at the end of the file:

USER_SETTINGS = UserSettings

无需重命名该类.

关于我的第二个问题-如何在测试中覆盖此类设置?我添加了一个名为utils.py的文件:

As for my second question - how do I override such settings in tests? I added a file called utils.py:

def get_django_settings_class_with_override_settings(django_settings_class, **override_settings):
    class django_settings_class_with_override_settings(django_settings_class):
        pass

    for setting, value in override_settings.items():
        setattr(django_settings_class_with_override_settings, setting, value)

    return django_settings_class_with_override_settings

(您可以在然后在测试中:

from django.conf import settings as django_settings
from django.test import override_settings

from speedy.core.settings import tests as tests_settings
from speedy.core.base.test.utils import get_django_settings_class_with_override_settings

    @override_settings(USER_SETTINGS=get_django_settings_class_with_override_settings(django_settings_class=django_settings.USER_SETTINGS, MAX_NUMBER_OF_FRIENDS_ALLOWED=tests_settings.OVERRIDE_USER_SETTINGS.MAX_NUMBER_OF_FRIENDS_ALLOWED))
    def test_user_can_send_friend_request_if_not_maximum(self):
        self.assertEqual(first=django_settings.USER_SETTINGS.MAX_NUMBER_OF_FRIENDS_ALLOWED, second=4)

我检查了一下,然后必须定义另一个类(在这种情况下为class django_settings_class_with_override_settings,因为如果直接更改类django_settings_class,它也会影响其他未使用@override_settings的测试.

I checked and I have to define another class (in this case, class django_settings_class_with_override_settings because if I change the class django_settings_class directly it also affects other tests which didn't use @override_settings.

这篇关于我可以在Django设置中定义类,如何在测试中覆盖此类设置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆