Есть ли простой способ заставить Django отображать {{myform.name}}
как
John Smith
вместо
<input id="id_name" name="name" value="John Smith" />
внутри тегов <form>
? Или я иду об этом неправильно?
Есть ли простой способ заставить Django отображать {{myform.name}}
как
John Smith
вместо
<input id="id_name" name="name" value="John Smith" />
внутри тегов <form>
? Или я иду об этом неправильно?
<form>
{% for field in form %}
{{ field.label }}: {{ field.value }}
{% endfor %}
</form>
Посмотрите здесь поля формы и Работа с формами
Старая тема, но я думаю, что некоторые люди все еще заходят сюда.
Вы также можете сделать что-то вроде этого:
from django.utils.safestring import mark_safe
class PlainTextWidget(forms.Widget):
def render(self, _name, value, _attrs):
return mark_safe(value) if value is not None else '-'
И в твоей форме
class SomeForm(Form):
somename = forms.CharField(widget=PlainTextWidget)
В Django 2.1+ вам понадобится следующее:
from django.utils.safestring import mark_safe
class PlainTextWidget(forms.Widget):
def render(self, name, value, attrs=None, renderer=None):
return mark_safe(value) if value is not None else '-'
def render(self, name, value, attrs):
в django 1.10 (? не уверен, есть ли это в других или почему моя версия не требует подчеркивания?), поэтому нет [_name и _attrs]
- person chris Frisina; 10.06.2018
Вы также можете использовать новый виджет: я сделал это, чтобы у меня был виджет, создающий текстовое отображение даты, и скрытая форма с той же датой в ней, чтобы она была видна пользователю, но не могла Измени это.
Вот первоначальная (все еще тестируемая/подлежащая очистке) версия:
class DayLabelWidget(forms.Widget):
def render(self, name, value, attrs):
final_attrs = self.build_attrs(attrs, name=name)
if hasattr(self, 'initial'):
value = self.initial
if type(value) == type(u''):
value = datetime.date(*map(int, value.split('-')))
return mark_safe(
"%s" % value.strftime("%A (%d %b %Y)")
) + mark_safe(
"<input type='hidden' name='%s' value='%s' />" % (
name, value
)
)
def _has_changed(self, initial, data):
return False
Затем вы используете это в поле как (widget=DayLabelWidget,)
.
Кроме того, не забывайте, что вы также можете сделать {{myform.instance.name}}
Я думаю, это то, что вам нужно: http://code.djangoproject.com/ticket/10427
Я пропатчил свой django и вуаля...
Почему бы не использовать {{ field.data }}?
Вот подход, предложенный @Matthew_Schinkel выше, с использованием Django 2.2 и python 3.
from django.utils.safestring import mark_safe
class PlainTextWidgetWithHiddenCopy(forms.Widget):
def render(self, name, value, attrs, renderer=None):
if hasattr(self, 'initial'):
value = self.initial
return mark_safe(
(str(value) if value is not None else '-') +
f"<input type='hidden' name='{name}' value='{value}'>"
)
Это настраиваемый виджет, который отображает содержимое поля в виде обычного текста, за которым следует HTML-тег, создающий скрытое поле с тем же именем и значением, что и у исходного поля.
Это означает, что помимо значения, отображаемого пользователю, оно сохраняется в браузере и отправляется далее представлению, которое обрабатывает отправленную форму.
Это особенно удобно, если форма выполняет POST саму себя, поскольку в противном случае данные открытого текста исчезли бы, поскольку значение поля initial
не было установлено.
Например, если ваша форма содержит:
my_field = forms.IntegerField(
widget=PlainTextWidgetWithHiddenCopy,
initial=12345)
то это поле будет отображаться как следующий HTML:
12345<input type='hidden' name='my_field' value='12345'>
При отправке формы данные POST, полученные соответствующим представлением, будут включать:
{'my_field': '12345'}
Это означает, что если представление теперь повторно отображает форму, значение my_field
снова устанавливается равным 12345
, как если бы запрос был GET
.
Как правильно отмечает Мэтью в своем последующем комментарии, этот подход не обеспечивает существенной защиты от изменения пользователем данных, отправленных обратно в скрытом поле. «Всякий пользовательский ввод — зло».