Jeremy D
Jeremy D

Reputation: 4855

Iterate through model fields in jinja template

I have several models in my application, and as I will have some views doing the same thing (form + tables showing existing records in my model), but implemented dfferently because of the model, which will be different in each case, I was wondering if it was possible to make it generic.

I googled a bit and was not able to find anything relevant to my case. What I would like to achieve:

In my view, I want to go through each object from the model that I passed to the template, for example:

return render_template('addstatus.html', form=form, statuses=Status.query.all(), 
        target_model="Status", fields=Status.__mapper__.c.keys())

But I want to have only one view, whatever the model will be, so I am not able to know in advance the fields of my model, the number of columns and so on.

I want to have something like that in my view:

{% for obj in objects %}
   {% for field in obj.fields %} (not existing)
      <h1> {{ field }} :: {{ obj.fields.field.value }}
   {% endfor %}
{% endfor %}

Is it something possible? How can I achieve that?

Upvotes: 4

Views: 4858

Answers (2)

Mark Hebert
Mark Hebert

Reputation: 959

I had a similar issue, and wanted something purely Jinja2 based. This will return all of the keys/fields in your "obj" table, and worked well for me:

obj.__table__.columns._data.keys()

Here it is implemented in your sample code

{% for obj in objects %}
    {% for field in obj.__table__.columns._data.keys() %}
        <h1> {{ field }} :: {{ obj[field] }} </h1>
    {% endfor %}
{% endfor %}

Upvotes: 0

ThiefMaster
ThiefMaster

Reputation: 318488

You can add this method to your db.Model class (either by subclassing or by monkeypatching):

from sqlalchemy.orm import class_mapper, ColumnProperty
def columns(self):
    """Return the actual columns of a SQLAlchemy-mapped object"""
    return [prop.key for prop in class_mapper(self.__class__).iterate_properties
            if isinstance(prop, ColumnProperty)]

Then you can use {% for col in obj.columns() %} to iterate over the column names.

Upvotes: 4

Related Questions