当数据库量比较大的时候一定要分页查询的
在django中操作数据库进行分页
queryset = models.PrettyNum.objects.all() #查询所有
queryset = models.PrettyNum.objects.all()[0:10] #查询出1-10列
queryset = models.PrettyNum.objects.filter(mobile__contains='136')[0:10] #查询出符合条件的前10列
queryset = models.PrettyNum.objects.all().count() #查询有多少条数据,返回的是一个数字
#第一页
queryset = models.PrettyNum.objects.all()[0:10]
#第二页
queryset = models.PrettyNum.objects.all()[10:20]
#第三页
queryset = models.PrettyNum.objects.all()[20:30]
1、封装分页的插件类
这个分页插件要实现的是如下效果,当前页和前5页,后5页,上一页和下一页,还有首页和尾页
在app01下创建一个分页的的工具类,pagination.py
pagination.py的内容:
在初始化函数中,需要的参数有
request:请求的对象,通过对象获取url传的参数
queryset:符合条件的数据(根据这个数据库给他镜像分页处理)
page_size: 每页显示多少条数据, 不传默认显示10条数据库
page_param:在URL中传递的获取分页的参数,例如 /pretty/list/?page=12, 默认是page
plus: 显示当前页的前或后几页(页码),默认是5
在初始化函数中计算出总页数
在函数html就是生成html页面,最后返回这个页码html页面的字符串
from django.utils.safestring import mark_safe
class Pagination():
def __init__(self,request,queryset,page_size=10,page_param="page",plus=5):
"""
:param request: 请求的对象
:param queryset: 符合条件的数据(根据这个数据库给他镜像分页处理)
:param page_size: 每页显示多少条数据
:param page_param: 在URL中传递的获取分页的参数,例如 /pretty/list/?page=12
:param plus: 显示当前页的前或后几页(页码)
"""
page = request.GET.get(page_param,"1")
if page.isdecimal():
page = int(page)
else:
page = 1
self.page = page
self.page_size = page_size
self.start = (page-1)* page_size
self.end = page * page_size
self.page_queryset = queryset[self.start:self.end]
total_count = queryset.count()
total_page_count,div = divmod(total_count,page_size)
if div:
total_page_count += 1
self.total_page_count = total_page_count
self.plus = plus
def html(self):
#计算出,显示当前页的前5页,后5页
if self.total_page_count <= 2 * self.plus + 1:
#数据库中的数据比较少,没有11页
start_page = 1
end_page = self.total_page_count
else:
# 数据库中的数据比较多,大于11页
# 当前页<5时,(小级值)
if self.page <= self.plus:
start_page = 1
end_page = 2 * self.plus + 1
else:
# 当前页大于5
#当前页 + 5 > 总页面
if (self.page + self.plus) > self.total_page_count:
start_page = self.total_page_count - 2*self.plus
end_page = self.total_page_count
else:
start_page = self.page - self.plus
end_page = self.page + self.plus
# 页码
page_str_list = []
page_str_list.append('<li><a href="?page={}">首页</a></li>'.format(1))
# 上一页
if self.page > 1:
prev = '<li><a href="?page={}">上一页</a></li>'.format(self.page -1)
else:
prev = '<li><a href="?page={}">上一页</a></li>'.format(1)
page_str_list.append(prev)
#页面
for i in range(start_page,end_page + 1):
if i == self.page:
ele = '<li class="active"><a href="?page={}">{}</a></li>'.format(i,i)
else:
ele = '<li><a href="?page={}">{}</a></li>'.format(i, i)
page_str_list.append(ele)
# 下一页
if self.page < self.total_page_count:
prev = '<li><a href="?page={}">下一页</a></li>'.format(self.page + 1)
else:
prev = '<li><a href="?page={}">下一页</a></li>'.format(self.total_page_count)
page_str_list.append(prev)
# 尾页
page_str_list.append('<li><a href="?page={}">尾页</a></li>'.format(self.total_page_count))
search_string = """
<li>
<form style="float:left; margin-left: -1px" method="get">
<input name="page" style="position: relative;float: left;display: inline-block;width: 80px;border-radius: 0" type="text" class="form-control" placeholder="页码">
<button style="border-radius: 0" class="btn btn-default" type="submit">跳转</button>
</form>
</li>
"""
page_str_list.append(search_string)
page_string = mark_safe("".join(page_str_list))
return page_string
2、在视图函数中使用页码类
在views.py 中导入类,实例化类,通过context 把内容传给页面
from django.shortcuts import render,redirect,HttpResponse
from django import forms
from app01 import models
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
from app01.utils.pagination import Pagination
def pretty_list(request):
"""靓号列表"""
data_dict = {}
search_data = request.GET.get('q',"")
if search_data:
data_dict['mobile__contains'] = search_data
#从数据库查询到数据,排序,使用order_by ,-level表示降序,level升序
queryset = models.PrettyNum.objects.filter(**data_dict).order_by("-level")
page_obj = Pagination(request,queryset)
context={
"search_data": search_data,
"queryset": page_obj.page_queryset, #分页的数据
"page_string":page_obj.html() #页码
}
return render(request,'pretty_list.html',context)
3、在html中展示页码
在pretty_list.html的底部加上显示页面的
不管在哪个页面需要使用页码,只需要在要展示的地方加上下面的页码展示的就可以了,具体有多少页,根据数据条数,自动生成在page_string 变量中
<nav aria-label="Page navigation">
<ul class="pagination">
{{ page_string }}
</ul>
</nav>
pretty_list.html的整体代码如下:
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<div style="margin-bottom: 10px">
<a class="btn btn-success" href="/pretty/add/">新建靓号</a>
<div style="float: right; width: 300px">
<form method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="手机号搜索" value="{{ search_data }}">
<span class="input-group-btn">
<button class="btn btn-default" type="submit">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading"><span class="glyphicon glyphicon-list" aria-hidden="true"></span> 靓号列表</div>
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>号码</th>
<th>价格</th>
<th>级别</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for obj in queryset %}
<tr>
<td>{{ obj.id }}</td>
<td>{{ obj.mobile }}</td>
<td>{{ obj.price }}</td>
<td>{{ obj.get_level_display }}</td>
<td>{{ obj.get_status_display }}</td>
<td>
<a class="btn btn-primary btn-xs" href="/pretty/{{ obj.id }}/edit/">编辑</a>
<a class="btn btn-danger btn-xs" href="/pretty/{{ obj.id }}/delete/">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<nav aria-label="Page navigation">
<ul class="pagination">
{{ page_string }}
</ul>
</nav>
</div>
{% endblock %}