Django @override_settings не позволяет словарь?
Я новичок в Python-декораторах, так что, возможно, мне не хватает чего-то простого, вот моя ситуация:
Это работает для меня:
def test_something(self):
settings.SETTING_DICT['key'] = True #no error
...
Но это выдает "SyntaxError: ключевое слово не может быть выражением":
@override_settings(SETTING_DICT['key'] = True) #error
def test_something(self):
...
Просто чтобы прояснить, нормальное использование настроек переопределения работает:
@override_settings(SETTING_VAR = True) #no error
def test_something(self):
...
Есть ли способ использовать декоратор со словарем настроек или я что-то не так делаю?
Заранее спасибо!
1 ответ
Вы должны переопределить весь диктовку:
@override_settings(SETTING_DICT={'key': True})
def test_something(self):
...
Или вы можете использовать override_settings
в качестве менеджера контекста:
def test_something(self):
value = settings.SETTING_DICT
value['key'] = True
with override_settings(SETTING_DICT=value):
...
Начиная с Python 3.3 вы можете использовать collections.Chainmap
если вы хотите переопределить определенные значения в объекте dict (или другом сопоставлении) с помощью декоратора и сохранить код чистым из диспетчера контекста. https://docs.python.org/3/library/collections.html
from collections import ChainMap
@override_settings(SETTING_DICT=ChainMap({'key': 'value'}, settings.SETTING_DICT))
def test_something(self):
...
Вышеупомянутое не переопределит весь dict и все другие значения в SETTINGS_DICT
будет доступно.
Для Python 2.7 вы можете использовать backport, который содержит Chainmap
реализация. https://pypi.org/project/chainmap/
Я также не хотел переопределять весь текст, поэтому скопировал соответствующий словарь из settings
объект и только что изменил интересующий меня атрибут:
import copy
from django.conf import settings
settings_dict = deepcopy(settings.SETTINGS_DICT)
settings_dict['key1']['key2'] = 'new value'
@override_settings(SETTINGS_DICT=settings_dict)
def test_something(self):
pass
Это соответствует моим целям, но если вы хотите сделать это более широко используемым, вы можете написать короткую функцию с несколькими аргументами, которая может делать что-то подобное динамически.
Примечание: я пытался использовать settings.SETTINGS_DICT.copy()
вместо deepcopy(settings.SETTINGS_DICT)
но это, казалось, глобально переопределяет настройку для всех тестов...
Самое простое решение для меня (работает с python 3.6):
@override_settings(SETTINGS_DICT={**SETTINGS_DICT, 'yournewkey': yournewvalue})