来自Django docs:
您不应在运行时更改应用程序中的设置。例如,不要在视图中执行此操作:
from django.conf import settings settings.DEBUG = True # Don't do this!
您应该为设置分配的唯一位置是设置文件。
我注意到Django测试代码does改变了设置。为什么可以在那里做到这一点?
简答:不,除非你在创业期间这样做。
答案很长:Django文档是正确的,你不应该在运行时修改设置。这意味着,应用程序启动后不会进行任何设置修改,例如更改views.py
,serializers.py
,models.py
或您在开发过程中添加的其他模块中的配置。但如果你在启动时这样做依赖于局部变量就可以修改设置,并且你完全了解会发生什么。
是的,如果你认为你需要它。在单元测试中,请随意依赖override_settings
更改设置值以进行测试,请参阅here的使用示例。此外,此装饰器所做的一切 - 覆盖了提供的值的设置,并在测试通过后恢复设置值(执行修饰函数)。
根据我的看法,他们仅为测试目的更改设置,他们唯一做的事情是 - 将本地主机添加到允许的主机,以便他们可以使用本地域测试代码。像这样的例子对我来说似乎很合理,因为改变只进行一次并且在单元测试设置期间。想象一下每次都有overrride_settings
呼叫,那将是滔天。
尽量不要,没有必要修改设置,如果有 - 想一想,也许设置不适合可变设置?如果你想在运行时修改设置 - 请注意,设置可能会被缓存到某个地方,复制和访问所有地方 - 这是一个充足的空间来容纳新的错误。除了因修改设置的旧/新值而导致系统出现意外行为外,没有什么不好的。
希望这是有道理的。
答案在于措辞:
您不应在运行时更改应用程序中的设置。
单元测试代码不是您的应用程序的一部分,因此该语句不适用于单元测试。
为什么可以在那里做到这一点?
如上所述,在测试期间覆盖设置是完全可以的,只要您以本地化方式执行(因为测试有时以多线程方式运行)。
以下是他们推荐的方式:
from django.test import TestCase
class LoginTestCase(TestCase):
def test_login(self):
# First check for the default behavior
response = self.client.get('/sekrit/')
self.assertRedirects(response, '/accounts/login/?next=/sekrit/')
# Then override the LOGIN_URL setting
with self.settings(LOGIN_URL='/other/login/'):
response = self.client.get('/sekrit/')
self.assertRedirects(response, '/other/login/?next=/sekrit/')
见文档:https://docs.djangoproject.com/en/2.2/topics/testing/tools/#django.test.SimpleTestCase.settings