Отображение значения в виде текста вместо поля внутри формы Django

Есть ли простой способ заставить Django отображать {{myform.name}} как

John Smith

вместо

<input id="id_name" name="name" value="John Smith" />

внутри тегов <form>? Или я иду об этом неправильно?


person ine    schedule 15.07.2009    source источник


Ответы (7)


<form>
    {% for field in form %}
            {{ field.label }}: {{ field.value }}
    {% endfor %}
</form>

Посмотрите здесь поля формы и Работа с формами

person tefozi    schedule 15.07.2009
comment
Спасибо - я видел .label, но не .initial. Любопытно, что .initial даже не упоминается в документе «Работа с формами». - person ine; 16.07.2009
comment
.initial работает только при первом представлении формы, верно? Например, если будут ошибки и вы повторно представите форму, инициала по моему опыту не будет. - person dfrankow; 21.08.2009
comment
В терминологии Django это работает только с несвязанными формами. Что, если вы хотите, чтобы он работал как с несвязанными, так и с связанными формами? - person dfrankow; 21.08.2009

Старая тема, но я думаю, что некоторые люди все еще заходят сюда.

Вы также можете сделать что-то вроде этого:

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 '-'
person caio    schedule 01.03.2011
comment
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,).

person Matthew Schinckel    schedule 20.07.2009
comment
Этот подход был очень полезен для меня, потому что он не только отображает «простую» версию значения, но и создает копию, которая передается при отправке формы. Я адаптировал его, чтобы сделать более общую версию (см. мой ответ ниже) - person Martin CR; 23.10.2019
comment
Имейте в виду, что это значение может быть легко изменено злоумышленником. Вероятно, вы захотите, чтобы поле формы возвращало исходное значение в чистоте. - person Matthew Schinckel; 28.10.2019
comment
Я согласен с этим. Подобные методы очень полезны для сохранения состояния на уровне представления, но ЛЮБОЙ элемент данных, отправленный обратно из пользовательской формы или сеанса, должен быть тщательно проверен, если он будет использоваться на уровне приложения. - person Martin CR; 29.10.2019

Кроме того, не забывайте, что вы также можете сделать {{myform.instance.name}}

person priestc    schedule 16.08.2009
comment
что это? где это задокументировано? - person dfrankow; 21.08.2009
comment
form.instance возвращает объект, который представляет связанная форма. Это в документах здесь: docs.djangoproject .com/en/dev/topics/forms/modelforms/ Я также должен упомянуть, что это работает только с моделями - person priestc; 21.08.2009
comment
ах, движок приложения Google не поддерживает ModelForm, поэтому мы используем Form. - person dfrankow; 21.08.2009

Я думаю, это то, что вам нужно: http://code.djangoproject.com/ticket/10427

Я пропатчил свой django и вуаля...

person Trunet    schedule 20.09.2010

Почему бы не использовать {{ field.data }}?

person alj    schedule 28.04.2010
comment
Потому что это нужно делать в представлениях, а не в шаблоне (в шаблоне есть цикл) - person Tomasz Brzezina; 09.08.2016

Вот подход, предложенный @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.

Как правильно отмечает Мэтью в своем последующем комментарии, этот подход не обеспечивает существенной защиты от изменения пользователем данных, отправленных обратно в скрытом поле. «Всякий пользовательский ввод — зло».

person Martin CR    schedule 23.10.2019