bigywater.tech
Flask · 57

自定义 Template Test

模板里的 {% if x is prime %} 是怎么回事?怎么写自己的测试?它和 {% if x %} 有什么区别?能给 select 过滤器用吗?这篇逐项实测。

45
本环境里的测试总数(含自己加的 6 个)
defined ≠ 真值
0 is defined 为 True,{% if 0 %} 为假
is
测试的语法(不是 ==)

自定义测试

实测 · 本机执行输出
  {% if 7 is prime %}7 是质数{% endif %}                        → 7 是质数
  {% if 8 is prime %}8 是质数{% else %}8 不是质数{% endif %}        → 8 不是质数
  {{ 11 is prime }}|{{ 12 is not prime }}                    → True|True
  {{ "hello" is longer_than(3) }}|{{ "hi" is longer_than 3 }} → True|False
  {{ user is adult }}                                        → True
  {{ d is weekend }}                                         → True
  {{ "a@b.co" is email }}|{{ "nope" is email }}              → True|False
  {{ doc is mine }}|{{ other is mine }}                      → True|False

上一篇:自定义 Template Global;下一篇:自动转义与 XSS 防护。

与 select 配合

实测 · 本机执行输出
   [2, 3, 5, 7] | [1, 4, 6, 8, 9, 10] | ['b']
  select("longer_than", 2): ['abc', 'abcd']

内置测试与真假值

实测 · 本机执行输出
  0 is defined           → True
  缺失 is defined          → False
  x is none(None)        → True
  x is none(0)           → False
  if x(0)                → 假
  x is true(1)           → False
  x is true(True)        → True
  "" is string           → True
  x is number(True)      → True
  4 is divisibleby 2     → True
  3 is odd               → True
  x is mapping           → True
  x is iterable(str)     → True
  x is callable          → True
  1 is eq 1              → True
  3 is ge 2              → True
  "a" is in ["a","b"]    → True
  x is sameas none       → True

出错的情况

实测 · 本机执行输出
  不存在的测试 → TemplateAssertionError: No test named 'nope'.
  缺少必需参数 → TypeError: longer_than() missing 1 required positional argument: 'n'
  给了多余的参数 → TypeError: is_prime() takes 1 positional argument but 2 were given
  对非整数用 prime(自己的函数返回 False 而不抛)→ False | 测试里没处理 None 时的报错(这里的 adult 收到 None): AttributeError: 'NoneType' object has no attribute 'get'

全部测试

实测 · 本机执行输出
  共 45 个: != < <= == > >= adult boolean callable defined divisibleby email eq equalto escaped even false filter float ge greaterthan gt in integer iterable le lessthan longer_than lower lt mapping mine ne none number odd prime sameas sequence string test true undefined upper weekend

三种写法的耗时

实测 · 本机执行输出
  n is prime(测试)           5.10 µs/次
  n|prime_f(过滤器)           5.11 µs/次
  prime_g(n)(全局函数)         6.41 µs/次

分步演示

模板测试
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.7 / Flask 3.1.3 / Werkzeug 3.1.9 / Jinja2 3.1.6 / SQLAlchemy 2.1.1 / gunicorn 26.2.0(都装在自己的虚拟环境里);大多数实验用 Flask 的 test_client(直接调用 WSGI 应用,不经过网络),需要真实 HTTP 时另起 gunicorn 或开发服务器(端口 9600 以上,本机 127.0.0.1);计时用 time.perf_counter,数字每次运行会有小幅抖动
    • 没有验证:test 在 Jinja2 沙箱里的限制、异步测试、测试名与过滤器名相同时的歧义、unittest 风格的模板单元测试
    京ICP备2026067502号-1京公网安备11010502063487号