Output Django Model as Table
Solution 1
So what you need to do is the following:
1) add
from django.forms import ModelForm
to your models.py
2) add
class My_Model_Form(ModelForm):
class Meta:
model = My_Model
3) in your views.py, change output = My_Model()
to output = My_Model_Form()
Now you are all set. So the trick is to inherit your Form from your original model.
Solution 2
If you're just looking to output one specific model, change your template to something like
<tr>
<td>Name:</td>
<td>{{ output.name}}</td>
</tr>
for all the fields you care about. If this is something you want to be able to do for any arbitrary model in your app, take a look at this snippet. That would provide you with a fields collection to loop over.
Solution 3
The models.Model
class doesn't have a method as_table()
like the forms.ModelForm
class does.
My solution was to also use template tags. I went with an inclusion tag.
myapp/templatetags/model_helpers.py
from django import template
register = template.Library()
@register.inclusion_tag('myapp/model_table.html', takes_context=True)
def model_as_table(context, model_key=None, model_table_attrs_key=None):
if model_key is None:
model_key = 'object'
if model_table_attrs_key is None:
model_table_attrs_key = 'model_table_attrs'
try:
attrs = context[model_table_attrs_key]
except KeyError:
attrs = context[model_key]._meta.get_all_field_names()
table_context = {'rows': []}
for attr in attrs:
try:
value = str(getattr(context[model_key], attr))
if value:
table_context['rows'].append({'attr': attr,
'value': context[model_key][attr]})
except AttributeError:
pass
# Needs a way to display many_to_many fields.
except StopIteration:
pass
return table_context
myapp/templates/myapp/model_table.html
{% for row in rows %}
<tr>
<td class="name">{{ row.attr }}</td>
<td class="field">{{ row.value }}</td>
</tr>
{% endfor %}
myapp/templates/myapp/outputtable.html
{% load model_helpers %}
<table>
{% model_as_table %}
</table>
With this implementation you can pass which model's attributes you want to display and in which order.
myapp/views.py
def output_table(request):
output = My_Model()
return render_to_response('outputtable.html',
{'output': output, 'model_table_attrs': ['attr1', 'attr2']})
I also like this cleanly separate html and python code.
Reznor
Updated on June 15, 2022Comments
-
Reznor almost 2 years
I have a view definition that (attempts to) outputs a model as a table. This is what I have so far:
def output_table(request): output = My_Model() return render_to_response('outputtable.html', {'output': output})
Here's the HTML for outputtable.html:
<html> <table> {{ output.as_table }} </table> </html>
What am I doing wrong? It doesn't work. Now, it's passing the model correctly, because if I change
My_Model()
toMy_Model.objects.all()
and then output it as simply{{ output }}
then it shows me what I would see in the Django shell.