Pagination and Filtering in Flask


Introduction

Pagination and filtering are essential features for APIs handling large datasets. Pagination divides data into smaller chunks, improving performance and user experience, while filtering allows users to retrieve only the relevant data they need.

In this article, we will implement pagination and filtering in Flask APIs using real examples.

Step 1: Setting Up Flask and Database

First, we need to set up a Flask application and a database. For this example, we will use SQLite with SQLAlchemy as the ORM.

            pip install flask
            pip install flask-sqlalchemy
        

Create a Flask application and define a database model:

            from flask import Flask
            from flask_sqlalchemy import SQLAlchemy

            app = Flask(__name__)
            app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data.db'
            db = SQLAlchemy(app)

            class Item(db.Model):
                id = db.Column(db.Integer, primary_key=True)
                name = db.Column(db.String(100))
                category = db.Column(db.String(100))

            db.create_all()
        

We have created an Item model with id, name, and category fields.

Step 2: Adding Sample Data

Add some sample data to the database:

            @app.route('/add_data')
            def add_data():
                items = [
                    Item(name='Laptop', category='Electronics'),
                    Item(name='Chair', category='Furniture'),
                    Item(name='Table', category='Furniture'),
                    Item(name='Smartphone', category='Electronics'),
                    Item(name='Pen', category='Stationery')
                ]
                db.session.add_all(items)
                db.session.commit()
                return "Data added!"
        

This route will add some sample items to the database.

Step 3: Implementing Pagination

Pagination allows clients to fetch data in smaller chunks. Here’s how to implement it:

            from flask import request, jsonify

            @app.route('/items')
            def get_items():
                page = request.args.get('page', 1, type=int)
                per_page = request.args.get('per_page', 2, type=int)
                items = Item.query.paginate(page=page, per_page=per_page, error_out=False)
                data = [
                    {"id": item.id, "name": item.name, "category": item.category}
                    for item in items.items
                ]
                return jsonify({
                    "data": data,
                    "total": items.total,
                    "page": items.page,
                    "pages": items.pages
                })
        

Here, we use paginate from SQLAlchemy to split results into pages. Clients can pass page and per_page as query parameters.

Testing Pagination

Start the Flask server and visit the following URL:

            http://localhost:5000/items?page=1&per_page=2
        

The response will show the first 2 items, total count, current page, and total pages.

Step 4: Implementing Filtering

Filtering allows clients to fetch data based on certain conditions. Here’s an example of category-based filtering:

            @app.route('/filter_items')
            def filter_items():
                category = request.args.get('category')
                items = Item.query.filter_by(category=category).all()
                data = [
                    {"id": item.id, "name": item.name, "category": item.category}
                    for item in items
                ]
                return jsonify(data)
        

In this example, we use filter_by to filter items by their category.

Testing Filtering

Visit the following URL to fetch items from the "Furniture" category:

            http://localhost:5000/filter_items?category=Furniture
        

The response will return all items under the "Furniture" category.

Step 5: Combining Pagination and Filtering

We can combine both pagination and filtering for more complex queries:

            @app.route('/search_items')
            def search_items():
                category = request.args.get('category')
                page = request.args.get('page', 1, type=int)
                per_page = request.args.get('per_page', 2, type=int)
                query = Item.query
                if category:
                    query = query.filter_by(category=category)
                items = query.paginate(page=page, per_page=per_page, error_out=False)
                data = [
                    {"id": item.id, "name": item.name, "category": item.category}
                    for item in items.items
                ]
                return jsonify({
                    "data": data,
                    "total": items.total,
                    "page": items.page,
                    "pages": items.pages
                })
        

This route supports filtering by category and paginates the results.

Testing Combined Query

Visit the following URL to fetch "Furniture" items, paginated:

            http://localhost:5000/search_items?category=Furniture&page=1&per_page=1
        

The response will return one item from the "Furniture" category.

Conclusion

In this article, we demonstrated how to implement pagination and filtering in Flask APIs using SQLAlchemy. These techniques help manage large datasets and improve API performance and usability. By combining pagination and filtering, you can provide flexible and efficient data retrieval in your Flask applications.





Advertisement