Output Django Model as Table

烈酒焚心 提交于 2021-02-07 13:30:21

问题


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() to My_Model.objects.all() and then output it as simply {{ output }} then it shows me what I would see in the Django shell.


回答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.




回答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.




回答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.




回答4:


There is no method as_table on a model instance (MyModel())or on Querysets (MyModel.objects.all()). You may have seen as_table as the forms method as_table. You don't have a form there.

If you want to print a model instance/ a queryset as a table, you will have to design it yourself.




回答5:


OMG this is old but Generic Views seem to be a good fit for this problem, for me at least. A List detail view should help me get running faster. :)




回答6:


I came up with a solution that worked for my specific need which renders any simple model's data into table rows. Add the following filter into templatetags/your_tags_file.py (don't forget the __init__.py file in the templatetags folder):

from django import template
register = template.Library()

@register.filter()
def as_table(model):
    ret = ""
    for name in model._meta.get_all_field_names():
        try:
            field = str(getattr(model, name))
            if field:
                ret += '<tr><td class="name">'+name+'</td><td class="field">'+field+'</td></td>'
        except AttributeError:
            pass
    return ret

In the template now you can just do:

{% load your_tags_file %}
<table>
    {{output|as_table|safe}}
</table>

This will render the model in a simple table for you. You can easily add any desired thead and tbody logic as you see fit by modifying the logic of how ret is generated. Hope this helps someone.



来源:https://stackoverflow.com/questions/2283611/output-django-model-as-table

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!