Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Flask-SQLAlchemy's Pagination class be used with a Python list?

I have a list of posts that I queried from SQLAlchemy. However, it's just a Python list now, not a query, so I can't use Flask-SQLAlchemy's query.paginate() method. Is it possible to use Flask-SQLAlchemy's Paginate class to paginate the list instead of a query?

from  flask_sqlalchemy import Pagination
from flask_app.model import Post
 
recommended_posts_title = ['the sea', 'loving better', 'someones mother']
posts = [Post.query.filter_by(title=title).first() for title in recommended_posts_title]
like image 867
goodnews john Avatar asked Oct 28 '25 04:10

goodnews john


2 Answers

You can use Flask-SQLAlchemy's Pagination class, but need to manually get the page number and slice the data.

The docs show the parameters that Pagination takes: Pagination(query, page, per_page, total, items).

Since we don't have a query in this case, we'll pass None for query. We'll get the page from the query string (http://localhost/home/posts?page=1), and use 20 for per_page. We can get total with len(), then slice our data to get 20 items from the page offset.

from flask_sqlalchemy import Pagination
from flask import Flask,request,render_template
from flask_app.model import Post

app = Flask(__name__)

@app.route("/recommended-posts", methods = ['GET'])
def recommended_post():
    recommended_titles = ['the sea', 'loving better', 'someones mother']
    posts = [Post.query.filter_by(title=title).first() for title in titles]
    page = request.args.get('page', 1, type=int)
    # get the start and end index based on page number
    start = (page - 1) * 20
    end = start + 20
    # page 1 is [0:20], page 2 is [20:41]
    items = posts[start:end]
    pagination = Pagination(None, page, 20, len(items), items)
    return render_template('blog/posts.html', pagination=pagination)

Use the pagination object as you normally would.

{% for item in pagination.items %}
    render post
{% endfor %}

{% if pagination.has_prev %}
    <a href="{{ url_for("recommended_posts", page=pagination.prev_num) }}">Previous</a>
{% endif %}

{% if pagination.has_next %}
    <a href="{{ url_for("recommended_posts", page=pagination.next_num) }}">Next</a>
{% endif %}
like image 175
goodnews john Avatar answered Oct 30 '25 10:10

goodnews john


For what it is still worth after more than a year:

I recently encountered the same issue since my results could not be obtained from a single query and had to be build it iteratively resulting in a "list of results".

Based on this answer, I came up with the following function to convert a list of results to a Pagination object:

from flask_sqlalchemy import Pagination

def paginate(data, page, per_page):
    # Based on page and per_page info, calculate start and end index of items to keep
    start_index = (page - 1) * per_page
    end_index = start_index + per_page

    # Get the paginated list of items
    items = data[start_index:end_index]

    # Create Pagination object
    return Pagination(None, page, per_page, len(data), items)
like image 22
Steven Robyns Avatar answered Oct 30 '25 10:10

Steven Robyns



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!