问题
I am working in a flask project (my very first project in flask) and I am having a problem when trying to paginate a query that contains a subquery. Just to put you in the picture I have three models: User, Magazine and Article. Each User is subscribed to several Magazines, each Article belongs to a Magazine. I am using queries and paginating the results in several parts of the code without any problem except when I am using a subquery. Below is the code where I am retrieving all the users subscribed to magazines a specific user (with id==2) is subscribed to:
sub = db.session.query(Magazine).join(Magazine.subscribers).filter(User.id == 2).subquery()
subscribers = db.session.query(User).select_from(sub).join(Magazine.subscribers)
this code works nice and in subscribers.all() there are the users that there should be. I have created a mockup where there are 5 users subscribed to a magazine the current user is also subscribed to. So the following code
print(len(subscribers.all()), ' friends:')
for s in subscribers.all(): print(s.name)
outputs "5 friends" and their names correctly. However, the problem arises when I try to paginate subscribers:
page=request.args.get('page', 1, type=int)
friends=subscribers.paginate(page, 3, False)
print('len(friends.items) ', len(friends.items))
for f in friends.items: print(f.name)
To start with, I am asking for 3 elements and len(friends.items) is 2. I have tryed asking for differents number of results and it always returns one less. Secondly, friends.has_next is False when it should be True: there are 5 elements in subscribers.all() and I have only asked for 3. For clarity let me put the code with some printing statements and its output:
from app import app, db
from app.models import *
from flask import render_template, url_for, request
@app.route('/')
@app.route('/index')
def index():
page=request.args.get('page', 1, type=int)
print('page: ', page)
sub = db.session.query(Magazine).join(Magazine.subscribers).filter(User.id == 2).subquery()
subscribers = db.session.query(User).select_from(sub).join(Magazine.subscribers)
print(len(subscribers.all()), ' friends:')
for s in subscribers.all(): print(s.name)
friends=subscribers.paginate(page, 3, False)
print('len(friends.items) ', len(friends.items))
for f in friends.items: print(f.name)
print('has_next: ', friends.has_next, ' has_previous ', friends. has_prev)
print('next_num: ', friends.next_num, ' prev_num: ', friends.prev_num)
next_url=url_for('index', page=friends.next_num) if friends.has_next else None
prev_url=url_for('index', page=friends.prev_num) if friends.has_prev else None
print(next_url)
print(prev_url)
return render_template("index.html", title="My friends", friends=friends.items, next_url=next_url, prev_url=prev_url)
And the output on the shell:
page: 1
5 friends:
biel
lluna
bruno
llucia
moix
len(friends.items) 2
biel
lluna
has_next: False has_previous False
next_num: None prev_num: None
None
None
This piece of code works perfectly if I change subscribers for some other query that does not use any subquery. What am I missing?!!
thanks a lot
来源:https://stackoverflow.com/questions/58282132/strange-paginate-behaviour-when-paginating-a-subquery-in-flask