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