Можете ли вы использовать регулярное выражение в условном шаблоне Django?

#python #django

#python #django

Вопрос:

Можно ли определить, удовлетворяет ли переменная шаблона в шаблоне Django регулярному выражению? В следующем шаблоне я хочу установить класс CSS для тега paragraph, который содержит текст справки, на основе того, удовлетворяет ли текст справки для этого поля регулярному выражению. Вот шаблон с добавленным псевдокодом:

 {% 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 всегда выполняются с использованием re модуля, который недоступен в шаблоне Django. Я также просмотрел документацию Django, но не смог найти способ сделать это.

Обновить

Я все еще не могу заставить этот код работать.

Мелвин, который ответил ниже, технически корректен. Вам следует избегать размещения условной логики в шаблонах Django. С этой целью я изменил свой шаблон в соответствии с документацией Django:

 {% 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 %}
 

Затем я добавил __init__ метод в свой класс forms ModelForm, который просматривает метки для полей формы, для которых не должен отображаться текст справки, и устанавливает 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 или пустую строку. Это какая-то проблема с синхронизацией или я допустил ошибку, которую я просто не вижу?

Комментарии:

1. docs.djangoproject.com/en/3.1/howto/custom-template-tags/…

2. Это вызвано тем, как ModelForm переопределяет вещи. по сути, вместо этого вы должны переопределить Meta.help_texts . Я не нашел, где это делает model form, но с обычной формой ваш код работает так, как ожидалось. Однако переопределение help_texts совершенно непрактично для вашего случая.

3. Хорошо, возможно, у вас та же проблема, что и у меня: модель формирует 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)
 

Перед нормализацией значения метки произошел сбой. Я использовал тест для прерывания PyCharm при назначении, но он так и не дошел до назначения, поэтому я остановился на операторе if, чтобы увидеть «Слышимый» вместо «слышимый».

Комментарии:

1. Я согласен, но это больше похоже на комментарий, чем на ответ

2. Спасибо, что дали мне знать. Я приму это к сведению.

3. Хорошо, подумал об этом. Нет, это ответ, потому что я решаю проблему X в задаче XY. Надеюсь, это помешает кому-либо написать тег шаблона, который выполняет регулярные выражения, потому что у нас достаточно этого плохого дизайна, лежащего на полу.

4. Я не против сущности, которую вы пытаетесь передать с помощью того, что вы написали. Лично я не нахожу привлекательными ни теги шаблонов, ни сам DTL в современную эпоху SPA, а также указываю, что следует учитывать логику (по крайней мере, это мое мнение), но для меня это обычно выглядит как материал для комментариев в одном предложении, может быть, это просто мое объединенное мнение о том, какой ответ и каконо должно быть кратким. Я немного отклонился от темы, так что извините за это, просто попытался уточнить, что я имел в виду.

5. @Melvyn Я бы хотел, но в настоящее время я не могу позволить себе тратить больше времени на эту проблему, тем более, что у меня есть обходной путь. Я отдал вам должное и очень ценю ваш ответ и вашу настойчивость в попытках помочь мне отследить источник проблемы. Еще раз спасибо.