源代码:https://github.com/daiguadaidai/django_pagination
2013年从开发转DB以来都没有写过网页了,最近想使用Django写点东西,在做准备的时候发现Django的插件实在难用(恶心)。具体为什么就不说了,所以就自己简单的实现了Django中分页。文章源自运维生存时间-https://www.ttlsa.com/python/django_self_pagination/
以下就介绍一下有关的分页代码在Django中的结构,和基本的使用含义。文章源自运维生存时间-https://www.ttlsa.com/python/django_self_pagination/
1.1. 项目基本结构
django_pagination ├── common │ └── util │ ├── pagination.py # 自己实现的分页代码 ├── db.sqlite3 ├── django_pagination │ ├── settings.py # 配置数据库 和 app │ ├── urls.py # 配置转跳链接 │ ├── wsgi.py ├── manage.py ├── mysite │ ├── admin.py │ ├── __init__.py │ ├── migrations │ ├── models.py # 关联数据库的model │ ├── templates │ │ ├── index.html # 显示分页的页面 │ ├── tests.py │ ├── views.py # 逻辑代码 ├── README.md └── sql └── mysite.sql # 数据库表结构和数据
1.2. 导入数据
mysql -uxxx -pyyy < sql/mysite.sql
1.3. 启动 server
python manage.py runserver 0.0.0.0:8000
1.4. 访问网页
http://127.0.0.1:8000/mysite/index
效果图(没有使用CSS美化):文章源自运维生存时间-https://www.ttlsa.com/python/django_self_pagination/
文章源自运维生存时间-https://www.ttlsa.com/python/django_self_pagination/
1.5. 看代码顺序
- 看 mysite/views.py 中的 index 方法
from django.shortcuts import render ## 导入分页的模块 ## from common.util.pagination import Pagination # Create your views here. def index(request): try: cur_page = int(request.GET.get('cur_page', '1')) # 获取当前的页码 except ValueError: cur_page = 1 # 创建分页数据 pagination = Pagination.create_pagination( from_name='mysite.models', # 数据库对应Model的模块文件 model_name='Employee', # 与数据库对应的Model cur_page=cur_page, # 传入当前的页码 start_page_omit_symbol = '...', # 页码(前)不够展示,使用什么符号表示 end_page_omit_symbol = '...', # 页码(后)不够展示,使用什么符号表示 one_page_data_size=10, # 每一页展示几条数据 show_page_item_len=9) # 页码显示个数 return render(request, 'index.html',{'pagination':pagination})
- 查看模板文件 mysite/templates/index.html
<h1>Employee List(Pagination)</h1> <li>emps: {{ pagination.objs }}</li> <table> <tr> <th>num</th> <th>name</th> <th>age</th> <th>gender</th> </tr> {% for emp in pagination.objs %} <tr> <td>{{ forloop.counter }}</td> <td>{{ emp.name }}</td> <td>{{ emp.age }}</td> <td> {% if emp.gender == 1 %} 男 {% elif emp.gender == 2 %} 女 {% else %} 其他 {% endif %} </td> </tr> {% endfor %} </table> <!-- 第一页, 上一页 --> {% if pagination.cur_page != 1 %} <a href="?cur_page=1"><<</a> <a href="?cur_page={{ pagination.pre_page }}"><</a> {% endif %} <!-- 省略号 --> {{ pagination.start_page_omit_symbol }} <!-- 能点击的页码 --> {% for page_item in pagination.page_items %} {% if page_item == pagination.cur_page %} {{ page_item }} {% else %} <a href="?cur_page={{ page_item }}">{{ page_item }}</a> {% endif %} {% endfor%} <!-- 省略号 --> {{ pagination.end_page_omit_symbol }} <!-- 下一页, 最后一页 --> {% if pagination.cur_page != pagination.all_page %} <a href="?cur_page={{ pagination.next_page }}">></a> <a href="?cur_page={{ pagination.all_page }}">>></a> {% endif %}
- 最后看分页主逻辑 common/util/pagination.py
class Pagination(object): """用于Model字段值的选择""" def __init__(self): pass @classmethod def create_pagination(self, from_name='', model_name='', cur_page=1, start_page_omit_symbol = '...', end_page_omit_symbol = '...', one_page_data_size=10, show_page_item_len=9): """通过给的model和分页参数对相关model进行分页 Args: from_name: 导入模块的 from后面的参数 from {from_name} import model_name mode_name: 需要导入的模块名 from from_name import {model_name} cur_page: 当前显示的是第几页 start_page_omit_symbol: 超出的页数使用怎么样的省略号(前) ... 2 3 4 end_page_omit_symbol: 超出的页数使用怎么样的省略号(后) 1 2 3 4 ... one_page_data_size: 每一页显示几行 show_page_item_len: 显示几个能点击的页数 Return: pagination: dict pagination = { 'objs': objs, # 需要显示model数据 'all_obj_counts': all_obj_counts, # 一共多少行数据 'start_pos': start_pos, # 数据分页开始的数据 'end_pos': end_pos, # 数据分页结束的数据 'all_page': all_page, # 一共有多少页 'cur_page': cur_page, # 当前的页码 'pre_page': pre_page, # 上一页的页码 'next_page': next_page, # 下一页的页码 'page_items': page_items, 能点击的页数 'start_page_omit_symbol': start_page_omit_symbol, # 开始的省略号 'end_page_omit_symbol': end_page_omit_symbol, # 结束的省略号 } Raise: None """ # 如果没有输入导入模块需要的相关信息直接退出 if not from_name or not model_name: return None import_str = 'from {from_name} import {model_name}'.format( from_name = from_name, model_name = model_name) # 导入模块 exec import_str start_pos = (cur_page - 1) * one_page_data_size end_pos = start_pos + one_page_data_size # 查找需要的model数据 find_objs_str = ('{model_name}.objects.all()' '[{start_pos}:{end_pos}]'.format( model_name = model_name, start_pos = start_pos, end_pos = end_pos)) objs = eval(find_objs_str) # 计算总共的页数 find_objs_count_str = '{model_name}.objects.count()'.format( model_name = model_name) all_obj_counts = eval(find_objs_count_str) all_page = all_obj_counts / one_page_data_size remain_obj = all_obj_counts % one_page_data_size if remain_obj > 0: all_page += 1 # 限制当前页不能小于1和并且大于总页数 cur_page = 1 if cur_page < 1 else cur_page cur_page = all_page if cur_page > all_page else cur_page # 获得显示页数的最小页 start_page = cur_page - show_page_item_len / 2 if start_page > all_page - show_page_item_len: start_page = all_page - show_page_item_len + 1 start_page = 1 if start_page < 1 else start_page # 获得显示页数的最大页 end_page = cur_page + show_page_item_len / 2 end_page = all_page if end_page > all_page else end_page if end_page < show_page_item_len and all_page > show_page_item_len: end_page = show_page_item_len # 获得上一页 pre_page = cur_page - 1 pre_page = 1 if pre_page < 1 else pre_page # 获得下一页 next_page = cur_page + 1 next_page = all_page if next_page > all_page else next_page # 处理省略符,是否显示 if start_page <= 1: start_page_omit_symbol = '' if end_page >= all_page: end_page_omit_symbol = '' # 创建能点击的展示页码 page_items = range(start_page, end_page + 1) pagination = { 'objs': objs, 'all_obj_counts': all_obj_counts, 'start_pos': start_pos, 'end_pos': end_pos, 'all_page': all_page, 'cur_page': cur_page, 'pre_page': pre_page, 'next_page': next_page, 'page_items': page_items, 'start_page_omit_symbol': start_page_omit_symbol, 'end_page_omit_symbol': end_page_omit_symbol, } return pagination
1.6. 程序的不足
该程序暂时还没有实现分页条件查询功能,其实添加也很简单,只是在添加一个入参就够了,有兴趣的可以修改一下代码直接用起来。文章源自运维生存时间-https://www.ttlsa.com/python/django_self_pagination/ 文章源自运维生存时间-https://www.ttlsa.com/python/django_self_pagination/

我的微信
微信公众号
扫一扫关注运维生存时间公众号,获取最新技术文章~
2F
为什么不用django自带的分页来继承就可以直接享受分页功能
1F
赞一个