你可以在 Django 模板条件中使用正则表达式吗?

Posted

技术标签:

【中文标题】你可以在 Django 模板条件中使用正则表达式吗?【英文标题】:Can you use a regular expression in a Django template conditional? 【发布时间】:2021-03-24 15:37:11 【问题描述】:

是否可以确定 Django 模板中的模板变量是否满足正则表达式?在下面的模板中,我想根据该字段的帮助文本是否满足正则表达式来为包含帮助文本的段落标签设置 CSS 类。这是带有一些伪代码的模板:

% for field in form.visible_fields %
  <div class="form-group">
     field.errors 
     field.label_tag   field 
    % if field.help_text %
      % if field.help_text|lower (BEGINS WITH SOME STRING) %         # Pseudocode
        <p class="select-help-text"> field.help_text|safe </p>
      % else %
        <p class="help-text"> field.help_text|safe </p>
      % endif %
    % endif %
  </div>
% endfor %

例如,如果关联表单中定义的 help_text 以文本字符串“按住 Ctrl”开头,则 CSS 类应设置为 select-help-text,否则应设置为 help-text

我了解 Django 正则表达式基于 Python 正则表达式,但 Python 正则表达式评估似乎总是使用在 Django 模板中无法访问的 re 模块完成。我还查看了 Django 文档,但找不到这样做的方法。

更新

我仍然无法让这段代码工作。

下面回答的梅尔文在技术上是正确的。您应该避免将条件逻辑放在 Django 模板中。为此,我根据 Django documentation 更改了我的模板:

% for field in form.visible_fields %
  <div class="form-group">
     field.errors 
     field.label_tag   field 
    % if field.help_text %
      <p class="help-text"> field.help_text|safe </p>
    % endif %
  </div>
% endfor %

然后,我在我的表单 ModelForm 类中添加了一个 __init__ 方法,该方法查看不应显示其帮助文本的表单字段的标签,并将 help_text 设置为“falsey”值,因此模板将失败:

def __init__(self, *args, **kwargs):
    super(MyModelForm, self).__init__(*args, **kwargs)
    for visible in self.visible_fields():
        if visible.field.label == 'foo' or visible.field.label == 'bar' or visible.field.label == 'baz':
            visible.field.help_text = False

但是,无论我将 help_text 设置为 False 还是 None 还是空字符串,我仍然可以看到帮助文本。这是某种时间问题还是我犯了一个我没有看到的错误?

【问题讨论】:

docs.djangoproject.com/en/3.1/howto/custom-template-tags/… 这是由 ModelForm 如何覆盖事物引起的。基本上,您应该改写 Meta.help_texts。我还没有找到模型形式在哪里可以做到这一点,但是使用正常形式,您的代码可以按预期工作。然而,覆盖 help_texts 对于您的情况是非常不切实际的。 好吧,你可能和我有同样的问题:模型表单title()他们的标签,所以你的匹配可能不匹配。 【参考方案1】:

DTL(Django 模板语言)不是用来编程的。事实上,我什至不会为此编写模板标签。在您的视图(或表单、字段或小部件)中,您有权将帮助文本更改为 2 元组或带有标签的 dict,所以为什么不这样做 ;)

也许最好的方法是在字段或小部件中,只需根据帮助文本将所需的类添加到小部件。

覆盖模型表单字段

所以,为了提供更新的答案,这是我使用的精简示例:

models.py

from django.db import models


class Sensor(models.Model):
    color = models.CharField(
        max_length=20, verbose_name="visible", help_text="Colors are visible"
    )
    sound = models.CharField(
        max_length=20, verbose_name="audible", help_text="Sounds are audible"
    )

forms.py


class BasicModelForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for visible in self.visible_fields():
            normalized = visible.label.lower()
            if "audible" == normalized:
                visible.help_text = ""

    class Meta:
        model = Sensor
        fields = "__all__"

tests.py

from django.template import Template, Context

class FormTest(TestCase):
    def test_modelform(self):
        form = BasicModelForm()
        self.assertEqual(form["sound"].help_text, "")

    def test_template(self):
        form = BasicModelForm()
        context = Context("form": form)
        template = Template(" form.sound.help_text  | form.color.help_text")
        actual = template.render(context)
        self.assertEqual(""" | Colors are visible""", actual)

在标准化标签值之前失败。我使用测试让 PyC​​harm 在分配时中断,但它从未完成分配,所以我在 if 语句处停下来看到“可听”而不是“可听”。

【讨论】:

我同意,但这看起来更像是评论而不是答案 感谢您告诉我。我会接受建议的。 好的,想了想。不,这是一个答案,因为我正在解决 XY 问题中的 X 问题。希望这可以防止有人编写执行正则表达式的模板标签,因为我们在这里有足够的糟糕设计。 我并不反对你试图用你写的东西来投射的本质。我个人并不觉得模板标签在现代 SPA 中具有吸引力,也没有 DTL 本身,并且还指出应该注意逻辑(至少这是我的观点),但这对我来说通常看起来像是一句话评论材料,也许是只是我对答案是什么以及它应该多么简洁的混合意见。我在这里有点跑题了,很抱歉,我只是想澄清一下我的意思。 @Melvyn 我会,但目前我不能在这个问题上花费更多时间,特别是因为我有一个解决方法。我确实给了您信任,并且非常感谢您的回答以及您坚持不懈地尝试帮助我找出问题的根源。再次感谢。

以上是关于你可以在 Django 模板条件中使用正则表达式吗?的主要内容,如果未能解决你的问题,请参考以下文章

可以在 JS 脚本中使用 Django 模板标签吗

使用“OR”条件的正则表达式

我可以评估 django 模板中的表达式吗?

Python之路-(js正则表达式前端页面的模板套用Django基础)

Django 模板三元运算符

在 Django 中,你可以让一个模板基础层从另一个继承吗?