Python案例怎么分页展示数据?

wen python案例 21

本文目录导读:

Python案例怎么分页展示数据?

  1. 基础实现(纯Python)
  2. Flask Web框架 + SQLAlchemy
  3. Django框架
  4. 命令行/终端分页展示
  5. Pandas DataFrame 分页
  6. API 分页(RESTful风格)
  7. 选择建议

在Python中分页展示数据有多种实现方式,主要取决于你使用的框架和场景,以下我为你整理几种常见方案:

基础实现(纯Python)

def paginate(data, page=1, per_page=10):
    """基础分页函数"""
    total = len(data)
    total_pages = (total + per_page - 1) // per_page  # 向上取整
    start = (page - 1) * per_page
    end = start + per_page
    # 确保不越界
    page_data = data[start:end] if start < total else []
    return {
        'data': page_data,
        'page': page,
        'per_page': per_page,
        'total': total,
        'total_pages': total_pages,
        'has_prev': page > 1,
        'has_next': page < total_pages
    }
# 使用示例
sample_data = list(range(1, 101))  # 100条数据
result = paginate(sample_data, page=2, per_page=10)
print(f"第{result['page']}页,共{result['total_pages']}页")
print(f"数据:{result['data']}")

Flask Web框架 + SQLAlchemy

from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy(app)
# 定义模型
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    email = db.Column(db.String(100))
@app.route('/users')
def get_users():
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 10, type=int)
    # SQLAlchemy自带分页方法
    pagination = User.query.paginate(
        page=page, 
        per_page=per_page, 
        error_out=False
    )
    users = [{
        'id': user.id,
        'name': user.name,
        'email': user.email
    } for user in pagination.items]
    return jsonify({
        'data': users,
        'pagination': {
            'page': pagination.page,
            'per_page': pagination.per_page,
            'total': pagination.total,
            'pages': pagination.pages,
            'has_prev': pagination.has_prev,
            'has_next': pagination.has_next
        }
    })

Django框架

from django.core.paginator import Paginator
from django.shortcuts import render
from .models import Article
def article_list(request):
    articles = Article.objects.all().order_by('-created_at')
    # Django自带分页器
    paginator = Paginator(articles, 10)  # 每页10条
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    return render(request, 'articles/list.html', {
        'page_obj': page_obj,
        'is_paginated': page_obj.has_other_pages()
    })
# 在模板中使用
"""
{% for article in page_obj %}
    <h2>{{ article.title }}</h2>
    <p>{{ article.content }}</p>
{% endfor %}
<div class="pagination">
    {% if page_obj.has_previous %}
        <a href="?page=1">&laquo; 第一页</a>
        <a href="?page={{ page_obj.previous_page_number }}">上一页</a>
    {% endif %}
    <span>第 {{ page_obj.number }} / {{ page_obj.paginator.num_pages }} 页</span>
    {% if page_obj.has_next %}
        <a href="?page={{ page_obj.next_page_number }}">下一页</a>
        <a href="?page={{ page_obj.paginator.num_pages }}">最后一页 &raquo;</a>
    {% endif %}
</div>
"""

命令行/终端分页展示

import os
import time
def display_paginated(data, page_size=5):
    """在终端分页显示数据"""
    total_items = len(data)
    total_pages = (total_items + page_size - 1) // page_size
    current_page = 1
    while True:
        os.system('cls' if os.name == 'nt' else 'clear')
        # 计算当前页数据
        start = (current_page - 1) * page_size
        end = start + page_size
        page_data = data[start:end]
        print(f"\n=== 第 {current_page}/{total_pages} 页 ===\n")
        for i, item in enumerate(page_data, start=start+1):
            print(f"{i}. {item}")
        print(f"\n{'='*30}")
        print("操作:n-下一页  p-上一页  q-退出")
        choice = input("请输入操作:").lower()
        if choice == 'n' and current_page < total_pages:
            current_page += 1
        elif choice == 'p' and current_page > 1:
            current_page -= 1
        elif choice == 'q':
            break
# 使用示例
data = [f"数据项{i}" for i in range(1, 51)]
display_paginated(data, page_size=10)

Pandas DataFrame 分页

import pandas as pd
def paginate_dataframe(df, page=1, page_size=10):
    """DataFrame分页"""
    total_rows = len(df)
    total_pages = (total_rows + page_size - 1) // page_size
    start_idx = (page - 1) * page_size
    end_idx = min(start_idx + page_size, total_rows)
    page_df = df.iloc[start_idx:end_idx]
    return {
        'data': page_df,
        'page': page,
        'page_size': page_size,
        'total_rows': total_rows,
        'total_pages': total_pages
    }
# 使用示例
df = pd.DataFrame({
    'name': [f'User{i}' for i in range(1, 101)],
    'score': [f'{i * 10}' for i in range(1, 101)]
})
result = paginate_dataframe(df, page=3, page_size=15)
print(result['data'])
print(f"当前页: {result['page']}, 共{result['total_pages']}页")

API 分页(RESTful风格)

from flask import Flask, request, jsonify
from urllib.parse import urlencode
app = Flask(__name__)
# 模拟数据
all_data = [{"id": i, "name": f"Item {i}"} for i in range(1, 101)]
@app.route('/api/items')
def get_items_api():
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 10, type=int)
    total = len(all_data)
    total_pages = (total + per_page - 1) // per_page
    start = (page - 1) * per_page
    end = start + per_page
    items = all_data[start:end]
    # 构建导航链接
    base_url = request.base_url
    links = {}
    if page > 1:
        params = {'page': page-1, 'per_page': per_page}
        links['prev'] = f"{base_url}?{urlencode(params)}"
    if page < total_pages:
        params = {'page': page+1, 'per_page': per_page}
        links['next'] = f"{base_url}?{urlencode(params)}"
    return jsonify({
        'data': items,
        'meta': {
            'page': page,
            'per_page': per_page,
            'total': total,
            'total_pages': total_pages
        },
        'links': links
    })

选择建议

  • 命令行工具:用基础实现 + 终端分页显示
  • Web应用:用框架自带的分页功能(Django Paginator / Flask-SQLAlchemy paginate)
  • API服务:使用RESTful风格分页,返回meta信息和导航链接
  • 数据分析:用Pandas DataFrame切片分页

每种方案都包含了常见的分页要素:

  • 当前页码
  • 每页数据量
  • 总数据量
  • 总页数
  • 上一页/下一页标志

根据你的具体使用场景选择合适的实现方式即可!

抱歉,评论功能暂时关闭!