You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django模板标签测试中自定义设置无法生效问题排查

问题根源:模块级变量的初始化时机

嘿,这个问题我之前也踩过坑!核心原因是模块级变量只会在Django启动/模块加载时初始化一次,后续修改settings根本不会更新它。

你看,你的DPS_TEMPLATE_TRUE_DEFAULT是定义在模板标签模块的顶级作用域里的,当Django加载这个模板标签模块时,getattr(settings, ...)就执行了,把值固定成了默认的"True"。之后不管你怎么修改settings(哪怕用override_settings或者pytest的settings fixture),这个变量都不会重新读取settings的值——因为它早就初始化完了。

更坑的是,你之前尝试把getattr移到函数默认参数里也没用,因为Python的函数默认参数是在函数定义时计算的,而不是每次调用函数时。所以哪怕你写成def get_var(name, rit=getattr(settings, ...), ...):,这个默认值还是只会计算一次,后续settings变化也不会生效。

解决方案:在函数内部动态读取settings

要解决这个问题,你需要把settings的读取逻辑移到函数体内部,每次调用模板标签时都去读取最新的settings值。这里有个优雅的写法,用哨兵值(比如None)作为默认参数,然后在函数里判断并动态获取:

# other imports
from django.conf import settings
from django import template

register = template.Library()

@register.simple_tag(name="var")
def get_var(name, rit=None, rif="False", rin=""):
    """ A template tag to render value of a variable. """
    _LOGGER.debug("Rendering value for `%s`...", name)
    
    # 动态读取settings,每次调用都获取最新值
    if rit is None:
        rit = getattr(settings, "DPS_TEMPLATE_TRUE_DEFAULT", "True")
    
    variable = models.Variable.objects.get(name=name)
    value = variable.value
    if value is None:
        return rin
    if isinstance(value, bool):
        if value:
            return rit
        else:
            return rif
    return variable.value

这样修改后,每次调用{% var %}模板标签时,都会实时读取当前的settings.DPS_TEMPLATE_TRUE_DEFAULT值,你的测试里修改的settings就能生效了。

测试验证

你的测试代码不需要大改,只要确保settings修改在模板渲染之前就行——pytest-django的settings fixture已经帮你做了这件事。运行测试后,应该能正确断言到"this is true by settings"的渲染结果。

另外,如果你之前硬编码settings.py没生效,也是因为模板标签模块早就加载了,改完settings后需要重启Django(或者测试进程)才能让模块重新加载。但用上面的动态读取方法,就再也不需要担心这个问题了。

内容的提问来源于stack exchange,提问作者Eray Erdin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:51:24