Django @override_settings不允许字典?

WBC*_*WBC 7 python testing django unit-testing django-settings

我是Python装饰者的新手,所以也许我错过了一些简单的东西,这是我的情况:

这对我有用:

def test_something(self):
    settings.SETTING_DICT['key'] = True #no error
    ...
Run Code Online (Sandbox Code Playgroud)

但这会抛出"SyntaxError:关键字不能是表达式":

@override_settings(SETTING_DICT['key'] = True) #error
def test_something(self):
   ...
Run Code Online (Sandbox Code Playgroud)

为了清楚起见,正常使用覆盖设置有效:

@override_settings(SETTING_VAR = True) #no error
def test_something(self):
   ...
Run Code Online (Sandbox Code Playgroud)

有没有办法将装饰器与设置字典一起使用,或者我做错了什么?

提前致谢!

ale*_*cxe 13

你应该覆盖整个字典:

@override_settings(SETTING_DICT={'key': True})
def test_something(self):
   ...
Run Code Online (Sandbox Code Playgroud)

或者,您可以将其override_settings用作上下文管理器:

def test_something(self):
     value = settings.SETTING_DICT
     value['key'] = True
     with override_settings(SETTING_DICT=value):
         ...
Run Code Online (Sandbox Code Playgroud)

  • 不过,覆盖整个字典并不会让其他键完好无损,对吗? (2认同)
  • 不,您要删除字典的其余设置。这对我来说不是正确的解决方案 (2认同)

def*_*nce 8

从 Python 3.3 开始,collections.Chainmap如果您想使用装饰器覆盖 dict(或其他映射)对象中的特定值并保持上下文管理器中的代码干净,则可以使用。 https://docs.python.org/3/library/collections.html#collections.ChainMap

from collections import ChainMap

@override_settings(SETTING_DICT=ChainMap({'key': 'value'}, settings.SETTING_DICT))
def test_something(self):
   ...
Run Code Online (Sandbox Code Playgroud)

上面的内容不会覆盖整个字典,并且所有其他值都SETTINGS_DICT将可用。

对于 Python 2.7,您可以使用向后移植,其中包含Chainmap实现。 https://pypi.org/project/chainmap/