Reputation: 4643
I want to modify the results from a flask-sqlalchemy query by before sending them to render_template()
.
The view queries and modifies the items:
items = Items.query
for i in items:
date = i.__dict__['date']
i.__dict__['date_modified'] = date.replace('/', '-')
return render_template('index.html', items=items)
When the template outputs the items:
{% for i in items %}{{i.date_modified}}{% endfor %}
This error is shown in the debugger:
KeyError: 'date_modified'
However, if I modify the initial query to get a pagination object, the error is not raised and the modified date appears.
items = Items.query
items = items.paginate(page_num, items_per_page, True).items
for i in items:
date = i.__dict__['date']
i.__dict__['date_modified'] = date.replace('/', '-')
return render_template('index.html', items=items)
What's the difference between the Query result and the Pagination result that allows the latter to be manipulated in place but not the former? How can I modify the results without modifying the query with paginate?
Upvotes: 0
Views: 1549
Reputation: 127180
In both examples you pass items
to the template. However, the items
value is different in each case.
In the first example, items
is the Query object from Items.query
. This value can be iterated over, which is why the for loop works. But the items need to be stored somewhere permanent. In the template, the query is iterated over again, and new Items instances are returned which were not modified in the view.
In the second example, items
is the result of paginate
, a list of Items
. When you modify each item, it is still stored in the list, and iterating over it again in the template results in the same items.
To solve the error from the first example, you need to store the references to the items being returned. The easiest way to do this is to force the query to return a list: items = Items.query.all()
.
Upvotes: 1