4

I'm using a generic DetailView to display a project object. Can I loop through the fields somehow in my template or do I have to place every field.

url(r'^(?P<slug>[-\w]+)/$', DetailView.as_view(model=Project,
                                               template_name='projects/detail_project.html',slug_field='slug',
                                                context_object_name='project'), name='project_detail'),

I've got something like this in my template:

{{ project.title }}
{{ project.created_date }}

etc...

Is there a way to do something like this?

    <table>
        {% for field in project %}
            <tr>
                <td>{{ field }}</td>
            </tr>
        {% endfor %}
    </table>

I tried the above snippet and got this error:

Caught TypeError while rendering: 'Project' object is not iterable
darren
  • 18,845
  • 17
  • 60
  • 79

1 Answers1

3

Usually its best to place each field, but ff you just want to dump all the fields you would could do something like:

# models.py
class Project(models.Model):
    ...

    def get_field_values(self):
        return [field.value_to_string(self) for field in Project._meta.fields]

then you could do

<table>
    {% for value in project.get_field_values %}
        <tr>
            <td>{{ value }}</td>
        </tr>
    {% endfor %}
</table>
JamesO
  • 25,178
  • 4
  • 40
  • 42
  • That's very cool. How would you handle a choices following this approach? Something like this : `ppr_tv_usages = models.IntegerField('Project Payment Responsibilities TV Usages', choices=PPR_CHOICES)` – darren Jul 14 '11 at 15:08
  • 1
    for choices you would need to call get_FOO_display() rather then field.value_to_string(self). Sure there is a better way to do this but altering get_field_values above to check if each field in meta has choices and if so calling something like getattr(self,"get_%s_display" % field.name)() would work. Hope that helps! – JamesO Jul 15 '11 at 14:54