1

How to increment the views value each time a post is retrieved using the Pagination object? For example, the below code results in TypeError: 'Pagination' object is not iterable:

@app.route('/myview/<int:page>')
def view(page=1):
    per_page = 10
    posts = Posts.query.order_by(Posts.time.desc()).paginate(page, per_page, error_out=False)
    for post in posts:
        post.views += 1
    db.session.commit()
    return render_template('view.html',posts=posts)
Greg
  • 8,175
  • 16
  • 72
  • 125
  • @Gerg can you please check without pagination(using .all()) what result you are getting – Mohammad Aarif Jul 28 '19 at 12:20
  • @MohammadAarif It works fine with `.all()` – Greg Jul 28 '19 at 12:26
  • @Greg, what is `views` in your case, a feature in the `Post` model? Or are you trying to update the result of the pagination itself? – realr Jul 29 '19 at 02:09
  • @calestini views is an integer column in the `Post` table. Not trying to update the result of the pagination object, only trying to record that the object/row has been retrieved/read from the database. – Greg Jul 29 '19 at 02:22

2 Answers2

1

From what I understand there are two things happening:

  1. Pagination of object Posts
  2. Saving a new information on each row that is retrieved

Part 1: Pagination is a class returned by paginate and the way to iterate through the elements is via items. That is why you are getting a TypeError when trying to iterate through the Pagination class. You can see more on the docs, or on this answer

The correct way to iterate would be:

for post in posts.items:
    # your code

Part 2: If you want to update the object as you iterate though it, you would also need to add it and commit. I am not sure the object can actually be updated as you are looping, but you could try:

session = db.session

for post in posts.items:
    post.views += 1
    session.add(post)

session.commit()
return render_template('view.html',posts=posts) 

If it does not work you can either append the ids to a list and update all at the end, or query and update inside the loop, using a different session.

posts_rendered = []
for post in posts.items:
    posts_rendered.append(post.id)

session.query(Posts).filter(Posts.id.in_(posts_rendered))\
    .update({Posts.views: Posts.views + 1})
session.commit()

A great response on updates can be found here

realr
  • 3,652
  • 6
  • 23
  • 34
0

you can not iterate directly paginate object-

you have to iterate on items -

for post in posts.itmes:
Mohammad Aarif
  • 1,619
  • 13
  • 19