Skip to content

Instantly share code, notes, and snippets.

@mozillazg
Created December 5, 2017 00:06
Show Gist options
  • Save mozillazg/69fb40067ae6d80386e10e105e6803c9 to your computer and use it in GitHub Desktop.
Save mozillazg/69fb40067ae6d80386e10e105e6803c9 to your computer and use it in GitHub Desktop.
A simple demo for how to use flask-paginate.

how to use

  1. pip install -U flask-paginate
  2. download app.py and index.html
  3. python app.py
  4. visit http://127.0.0.1:5000/
from flask import Flask, render_template
from flask_paginate import Pagination, get_page_args
app = Flask(__name__)
app.template_folder = ''
users = list(range(100))
def get_users(offset=0, per_page=10):
return users[offset: offset + per_page]
@app.route('/')
def index():
page, per_page, offset = get_page_args(page_parameter='page',
per_page_parameter='per_page')
total = len(users)
pagination_users = get_users(offset=offset, per_page=per_page)
pagination = Pagination(page=page, per_page=per_page, total=total,
css_framework='bootstrap4')
return render_template('index.html',
users=pagination_users,
page=page,
per_page=per_page,
pagination=pagination,
)
if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>flask-bootstrap example</title>
<!-- Bootstrap -->
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css">
</head>
<body>
<div class="container">
{{ pagination.links }}
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>#</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ loop.index + (page - 1) * per_page }}</td>
<td>{{ user }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{{ pagination.links }}
</div>
</body>
</html>
@RishikMani
Copy link

Thank you very much for this pretty clean code. I was trying to implement paging on a panda dataframe. Although, the page links got created, but they are not aligned properly and moreover the dataset was not paged. I am doing a different task as compared to you and my html also is different as compared to you.

Do you understand what might be wrong here?

Please take a look at the attachment.
paging

@ayoyu
Copy link

ayoyu commented Nov 28, 2018

Hi, interesting as a method to paginate items.I just want to know how can we change the default value of offset, because the default incrementation of this value is by 10, even when we change the per_page value?

@Lbzttt
Copy link

Lbzttt commented Dec 9, 2018

@RishikMani
For the renderting problem.
I had the same problem and specifying the css framework solved it for me.
pagination = (..., css_framework='bootstrap3')

@RishikMani
Copy link

Hi, interesting as a method to paginate items.I just want to know how can we change the default value of offset, because the default incrementation of this value is by 10, even when we change the per_page value?

@ayoyu you should go to the get_page_args function and then you would see the following line:
if not per+page:
per_page = current.app.config.get(per_page_name.upper(), 10)

Here you can change the value to whatever number you want.

@shekabhi961
Copy link

shekabhi961 commented Sep 17, 2019

i want to paginate this but i stuck in problem, i'm a beginner please help this is code and html below

app.py

@app.route('/chats', methods=['GET', 'POST'])
def chats(): #page
if 'lid' in session:
id = session['lid']
uid = session['uid']

    # Create cursor
    cur=mysql.connection.cursor()
    cur.execute("SELECT * FROM message WHERE (msg_by=%s AND msg_to=%s) OR(msg_by= %s AND msg_to = %s) "
                "ORDER BY id ASC ", [uid, id, id, uid] )
    chats = cur.fetchall()
    # Close Connection
    cur.close()

    return render_template('chats.html',chats=chats)
return redirect(url_for('login'))

chats_room.html

{% if session.lid %} {% if session.name != session.s_name %}
{{ session.name}}
               <div id="posts"></div>
                <span style="float: right;display: inline-block;"></span>
            </div>

            {% from "includes/_formhelpers.html" import render_field %}
            <div>
                <form method="POST" action="">
                <div class="form-group">
                    {{render_field(form.body, class_="form-control", value="", placeholder="Enter your text...")}}
                </div>
                   

                <button type="submit" class="btn btn-primary pull-right">Send</button>
                </form>
            </div>

        {% else %}
            <div style="text-align: center;">
                <h1>Welcome to Chat Room</h1>
                <p class="lead">Select users and start chat...</p>
            </div>
        {% endif %}
    {% endif %}



</div>
<div class="col-xs-1"></div>

Copy link

ghost commented Oct 10, 2019

Hi, interesting as a method to paginate items.I just want to know how can we change the default value of offset, because the default incrementation of this value is by 10, even when we change the per_page value?

Hi did you ever find a way to change the default value. I would 5 records.

@Daveinthebigcity
Copy link

Daveinthebigcity commented Dec 9, 2019

This is a good tutorial. I managed to get the pagination to work for 10 results but can't find a way to change the per_page value to return > 10 results. Any suggestions on how to access per_page = current.app.config.get(per_page_name.upper(), 10) would be greatly appreciated!

Edit: I managed to suss it out in the end. I found the init file in the site packages and then edited it directly. For anyone else stuck on this: (Using Windows) I navigated to......
C:\myProjectName\lib\site-packages\flask_paginate.

Once in that folder you can find the init file. Open it and search for current_app.config.get(per_page_name.upper(), 10). You can then hard code this value to whatever you want.

@poncellat
Copy link

poncellat commented Dec 13, 2019

Hi, interesting as a method to paginate items.I just want to know how can we change the default value of offset, because the default incrementation of this value is by 10, even when we change the per_page value?

@ayoyu
@Lars7

Informal reply.

There are three ways of doing it.

  1. By re-assigning per_page value in app.py right after get_page_args()
   page, per_page, offset = get_page_args(page_parameter='page',
                                           per_page_parameter='per_page')

    per_page = 10
  1. Through request parameter
    http://localhost:1555/?per_page=10

  2. By changing the flask_paginate module's __init__.py

    if not per_page:
        per_page = current_app.config.get(per_page_name.upper(), 10)
    else:
        per_page = int(per_page)

    offset = (page - 1) * per_page```

@egy1st
Copy link

egy1st commented Apr 1, 2020

Hi, interesting as a method to paginate items.I just want to know how can we change the default value of offset, because the default incrementation of this value is by 10, even when we change the per_page value?

@ayoyu you should go to the get_page_args function and then you would see the following line:
if not per+page:
per_page = current.app.config.get(per_page_name.upper(), 10)

Here you can change the value to whatever number you want.

This is a hardcoded way, which is not recommnded as it will change it through all the use of your pagination function
simply add an additional parameter to your function
pagination_users = get_users(page=page, offset=offset, per_page=per_page)

then use it as following
def get_users(page, offset=0, per_page=10):
offset = (page-1) * my_own_offset)
return users[offset: offset + per_page]

@seabass118
Copy link

This is the best solution to overwrite the per_page value.

def get_items(page, offset=0, per_page=10):
per_page = 50
offset = ((page - 1) * per_page)
return items[offset: offset + per_page]

@GaneshGS
Copy link

Hi,
Thanks for such a wonderful presentation of pagination with flask. I am extracting data from Mongodb with post requests and implementing paginiation. It is showing first page (per_page) list on the webpage but not allowing me to make get requests to call the second and third page. If I bypass post request, I am not able to get data from forms. Any idea of handling pagination in this situation?

@anaveronicaaponte
Copy link

anaveronicaaponte commented Oct 7, 2021

Hello! This is what I was looking for! But I just have a problem, I don't want to use the get_users() function because I already have a SQLite database in my Flask web application. Any advice on how to acheive this through my database?

EDIT: if anybody is wondering, I fixed it. This is my get_users() function (importing sqlite3 module of course):

def get_users(page=1, total=100, per_page=5):
    offset = total - ((page - 1) * per_page) + 1
    con = sqlite3.connect('database.db')
    cur = con.cursor()
    query = '''SELECT column1, column2
                FROM table
                WHERE entry_id < ?
                ORDER BY entry_id DESC
                LIMIT ?;'''
    cur.execute(query, (offset, per_page))
    users = cur.fetchall()
    cur.close()
    con.close()
    return users

And then I modified a bit the index function:

@app.route('/')
def index():
    con = sqlite3.connect('database.db')
    cur = con.cursor()
    page, per_page, offset = get_page_args(page_parameter='page', # I don't use this offset value at all
                                           per_page_parameter='per_page')
    per_page = 5
    cur.execute("SELECT COUNT(entry_id) FROM history")
    total = cur.fetchone()[0]
    cur.close()
    con.close()
    pagination_users = get_users(page=page, total=total, per_page=per_page)
    pagination = Pagination(page=page, per_page=per_page, total=total)
    return render_template('index.html',
                           users=pagination_users,
                           page=page,
                           per_page=per_page,
                           pagination=pagination)

@markdimi
Copy link

markdimi commented Dec 8, 2022

Hello!

@anaveronicaaponte pointed me to the right direction since I am not using SQLalchemy for my db.
Just sqlite (like the official tutorial).

The only problem I had with the above solution was that the results of the first page weren't visible. I fixed this issue by using the offset value from the get_page_args function inside the query of the get_users function, instead of the calculation :

offset = total - ((page - 1) * per_page) + 1

@gmanoukian
Copy link

Dear: the correct way to solve this is like this, it is not necessary to modify anything, I leave the solution in case anyone is interested.

Originally:
page, per_page, offset = get_page_args(page_parameter='page',per_page_parameter='per_page')

Correct:
page, per_page, offset = get_page_args(page_parameter='page',per_page_parameter='per_page',per_page='5')

Best regards

@vickykavthankar
Copy link

thanks @gmanoukian

@vigindian
Copy link

For anyone else struggling to get dataframe + pagination working, this method works - https://www.thepythoncode.com/article/convert-pandas-dataframe-to-html-table-python. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment