[ACCEPTED]-Rendering a value as text instead of field inside a Django Form-django-forms

Accepted answer
Score: 22
<form>
    {% for field in form %}
            {{ field.label }}: {{ field.value }}
    {% endfor %}
</form>

Take a look here Form fields and Working with forms

0

Score: 18

Old topic, but I think some people still 3 comes here.

You can do something like this 2 too:

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 '-'

And in your form

class SomeForm(Form):
   somename = forms.CharField(widget=PlainTextWidget)

Under Django 2.1+ you'll 1 need the following:

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 '-'
Score: 6

Also, don't forget you can also do {{myform.instance.name}}

0

Score: 5

You can also use a new widget: I did this 7 so that I could have a widget that created 6 a text display of a date, and a hidden form 5 with the same date in it, so it could be 4 visible to the user, but they cannot change 3 it.

Here is an initial (still testing/to 2 be cleaned up) version:

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

You then use this 1 in the field as (widget=DayLabelWidget,).

Score: 3

I think this is what you want: http://code.djangoproject.com/ticket/10427

I patched 1 my django and voila...

Score: 2

Why not use {{ field.data }} ?

0

Score: 2

Here is a take on the approach suggested 25 by @Matthew_Schinkel above, using Django 24 2.2 and 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}'>"
        )

This is a custom widget 23 that renders the contents of a field as 22 plaintext followed by an html tag that creates 21 a hidden field with the same name and value 20 as the original field.

This means that as 19 well as the value being displayed to the 18 user, it is held by the browser and sent 17 onwards to the view that processes the submitted 16 form.

This is particularly handy if the form 15 POSTs to itself, as the plaintext data would 14 otherwise disappear because the field's 13 initial value hadn’t been set.

For example if your 12 form contains:

my_field = forms.IntegerField(
    widget=PlainTextWidgetWithHiddenCopy,
    initial=12345)

then this field will render 11 as the following html:

12345<input type='hidden' name='my_field' value='12345'>

When the form is submitted 10 the POST data received by the corresponding 9 view will include:

{'my_field': '12345'}

This means that if the 8 view now re-renders the form then the value 7 of my_field is again set to 12345 just as if the request 6 had been a GET.

As Matthew correctly points 5 out in his subsequent comment, this approach 4 provides no significant protection against 3 a user changing the data that’s sent back 2 in the hidden field. “All user input is 1 evil”.

More Related questions