Django @override_settings does not allow dictionary?

♀尐吖头ヾ 提交于 2020-01-30 04:32:48

问题


I am new to Python decorators so perhaps I am missing something simple, here is my situation:

This works for me:

def test_something(self):
    settings.SETTING_DICT['key'] = True #no error
    ...

But this throws a "SyntaxError: keyword can't be an expression":

@override_settings(SETTING_DICT['key'] = True) #error
def test_something(self):
   ...

Just to be clear, normal use of override settings works:

@override_settings(SETTING_VAR = True) #no error
def test_something(self):
   ...

Is there a way to use the decorator with a settings dictionary, or am I doing something wrong?

Thanks in advance!


回答1:


You should override the whole dict:

@override_settings(SETTING_DICT={'key': True})
def test_something(self):
   ...

Or, you can use override_settings as a context manager:

def test_something(self):
     value = settings.SETTING_DICT
     value['key'] = True
     with override_settings(SETTING_DICT=value):
         ...



回答2:


I didn't want to override the whole dict either, so I copied the dictionary in question from the settings object and just modified the attribute I was interested in:

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

It suits my purposes, but if you wanted to make this more widely usable, you could write a short function with a few arguments which could do something like this dynamically.

Note: I tried using settings.SETTINGS_DICT.copy() instead of deepcopy(settings.SETTINGS_DICT) but that seemed to globally override the setting for all tests...




回答3:


Since Python 3.3, you may use colections.Chainmap if you wand to override specific values in the dict (or other mapping) object using decorator and keep code clean from context manager. https://docs.python.org/3.7/library/collections.html#collections.ChainMap

from collections import ChainMap

@override_settings(SETTING_DICT=ChainMap({'key': 'value'}, settings.SETTING_DICT))
def test_something(self):
   ...

The above will not override whole dict, and all other values in SETTINGS_DICT will be available.

For Python 2.7 you may use backport, which contains Chainmap implementation. https://pypi.org/project/chainmap/



来源:https://stackoverflow.com/questions/24214636/django-override-settings-does-not-allow-dictionary

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!