The ListView works like a dream. The ModelForm works a dream and on the edit link I can simply display the form by including {{ form }} in a generic template. What a beautifully fficient generic way of rendering quick test forms and such. Love it.
Now I want to do same with a DetailView, i.e. render a page that just shows me Object 1 say much like my ModelForm does but not as a form as a readonly display, using labels not fields:
The form say provides:
<tr><th><label for="id_prop1">Label 1:</label></th><td><input id="id_prop1" ... /></td></tr>
<tr><th><label for="id_prop2">Label 2:</label></th><td><input id="id_prop2" ... /></td></tr>
<tr><th><label for="id_prop3">Label 3:</label></th><td><input id="id_prop3" ... /></td></tr>
<tr><th><label for="id_prop4">Label 4:</label></th><td><input id="id_prop4" ... /></td></tr>
Can DetailView not provide me with something similar, like:<tr><th>Label 1:</th><td>Value 1</td></tr>
<tr><th>Label 2:</th><td>Value 2</td></tr>
<tr><th>Label 3:</th><td>Value 3</td></tr>
<tr><th>Label 4:</th><td>Value 4</td></tr>
I find it hard to believe not, but danged if I can find it!
An odd inconsistency if so. Do I really have to derive a class DetailViewWithHTML from it and write my own wrappers?
Regards,
Bernd.
from django.utils import six
from django.utils.safestring import mark_safe
from django.utils.html import conditional_escape
from django.utils.encoding import force_text
from django.forms.models import model_to_dict, fields_for_model
class DetailViewWithHTML(DetailView):
fields = None
field_data = None
def __init__(self, instance):
self.fields = fields_for_model(self.model)
self.field_data = model_to_dict(instance)
# HTML formatters stolen straight form the Django ModelForm class
def _html_output(self, normal_row, help_text_html):
"Helper function for outputting HTML. Used by as_table(), as_ul(), as_p()."
output = []
for name, field in self.fields.items():
value = self.field_data[name]
if field.label:
label = conditional_escape(force_text(field.label))
else:
label = ''
if field.help_text:
help_text = help_text_html % force_text(field.help_text)
else:
help_text = ''
output.append(normal_row % {
'label': force_text(label),
'value': six.text_type(value),
'help_text': help_text,
})
return mark_safe('\n'.join(output))
def as_table(self):
"Returns this form rendered as HTML <tr>s -- excluding the <table></table>."
return self._html_output(
normal_row='<tr><th>%(label)s</th><td>%(value)s%(help_text)s</td></tr>',
help_text_html='<br /><span class="helptext">%s</span>')
def as_ul(self):
"Returns this form rendered as HTML <li>s -- excluding the <ul></ul>."
return self._html_output(
normal_row='<li>%(errors)s%(label)s %(value)s%(help_text)s</li>',
help_text_html=' <span class="helptext">%s</span>')
def as_p(self):
"Returns this form rendered as HTML <p>s."
return self._html_output(
normal_row='<p>%(label)s %(value)s%(help_text)s</p>',
help_text_html=' <span class="helptext">%s</span>')