django mysql分页_Django基础之django分页

一、Django的内置分页器(paginator)

view

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

48304ba5e6f9fe08f3fa1abda7d326ab.png

from django.shortcuts import render,HttpResponse

# Create your views here.

from app01.models import *

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

def index(request):

'''

批量导入数据:

Booklist=[]

for i in range(100):

Booklist.append(Book(title="book"+str(i),price=30+i*i))

Book.objects.bulk_create(Booklist)

'''

'''

分页器的使用:

book_list=Book.objects.all()

paginator = Paginator(book_list, 10)

print("count:",paginator.count) #数据总数

print("num_pages",paginator.num_pages) #总页数

print("page_range",paginator.page_range) #页码的列表

page1=paginator.page(1) #第1页的page对象

for i in page1: #遍历第1页的所有数据对象

print(i)

print(page1.object_list) #第1页的所有数据

page2=paginator.page(2)

print(page2.has_next()) #是否有下一页

print(page2.next_page_number()) #下一页的页码

print(page2.has_previous()) #是否有上一页

print(page2.previous_page_number()) #上一页的页码

# 抛错

#page=paginator.page(12) # error:EmptyPage 超过页码范围

#page=paginator.page("z") # error:PageNotAnInteger 非法页码值

#page = page_obj.page(-1) #That page number is less than 1 ,也是EmptyPage的错误,页码不能为负数,最少也是1

'''

book_list=Book.objects.all()

paginator = Paginator(book_list, 10) #按照每页显示10条来计算

page = request.GET.get('page',1) #将来访问的url是这样的 http://127.0.0.1:8000/路径/?page=1

currentPage=int(page)

try:

print(page)

book_list = paginator.page(page)

except PageNotAnInteger:

book_list = paginator.page(1)

except EmptyPage:

book_list = paginator.page(paginator.num_pages)

return render(request,"index.html",{"book_list":book_list,"paginator":paginator,"currentPage":currentPage})

48304ba5e6f9fe08f3fa1abda7d326ab.png

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

index.html:

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

48304ba5e6f9fe08f3fa1abda7d326ab.png

Title

integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

分页器

{% for book in book_list %}

{{ book.title }} -----{{ book.price }}

{% endfor %}

{% if book_list.has_previous %}

上一页

{% else %}

上一页

{% endif %}

{% for num in paginator.page_range %}

{% if num == currentPage %}

{{ num }}

{% else %}

{{ num }}

{% endif %}

{% endfor %}

{% if book_list.has_next %}

下一页

{% else %}

下一页

{% endif %}

48304ba5e6f9fe08f3fa1abda7d326ab.png

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

扩展

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

from django.core.paginator import Paginator,PageNotAnInteger,EmptyPage

def show(request):

book_objs = models.Book.objects.all()

page_obj = Paginator(book_objs,1)

print('数据总数',page_obj.count)

print('总页数',page_obj.num_pages)

print('页码列表',page_obj.page_range)

page1 = page_obj.page(1)

for i in page1:

print(i)

print(page1.object_list)

page2 = page_obj.page(2)

print(page2.has_previous())

print(page2.has_next())

print(page2.next_page_number())

print(page2.previous_page_number())

# page = page_obj.page(-1)

page_num = request.GET.get('page',1)

try:

current_page_num = int(page_num)

page_num_data = page_obj.page(current_page_num)

except PageNotAnInteger:

current_page_num = 1

page_num_data = page_obj.page(current_page_num)

except EmptyPage:

current_page_num = page_obj.num_pages

page_num_data = page_obj.page(current_page_num)

except Exception:

current_page_num = 1

page_num_data = page_obj.page(current_page_num)

if page_obj.num_pages > 11: #扩展,如果总的页码数大于了11,我们就不把所有的页码数显示出来了,只显示其中11个页面,当前页左边5个,右边5个

if current_page_num - 5 < 1:

pageRange = range(1,12)

elif current_page_num + 5 > page_obj.num_pages:

pageRange = range(page_obj.num_pages-10,page_obj.num_pages+1)

else:

pageRange = range(current_page_num - 5,current_page_num + 6)

else:

pageRange = page_obj.page_range

book_objs = page_num_data

return render(request,'show.html',{'book_objs':book_objs,'current_page_num':current_page_num,'page_obj':page_obj,'pageRange':pageRange})

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

show.html

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

{% load static %}

Title

数据展示

idtitle价格性别出版日期出版社作者操作

{% for book_obj in book_objs %}

{{ book_obj.pk }}{{ book_obj.title }}{{ book_obj.price }}{{ book_obj.get_sex_display }}{{ book_obj.publishDate|date:'Y-d-m' }}{{ book_obj.publish.name }}

{% for author in book_obj.authors.all %}

{{ author.name }}

{% endfor %}

编辑

删除

{% endfor %}

{% if book_objs.has_previous %}

上一页

{% else %}

上一页

{% endif %}

{% for num in pageRange %}

{% if num == current_page_num %}

{{ num }}

{% else %}

{{ num }}

{% endif %}

{% endfor %}

{% if book_objs.has_next %}

下一页

{% else %}

下一页

{% endif %}

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

model.py文件内容:

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

from django.db import models

# Create your models here.

class Author(models.Model):

nid = models.AutoField(primary_key=True)

name=models.CharField( max_length=32)

age=models.IntegerField()

authorDetail=models.OneToOneField(to="AuthorDetail",to_field="nid")

def __str__(self):

return self.name

class AuthorDetail(models.Model):

nid = models.AutoField(primary_key=True)

birthday=models.DateField()

telephone=models.BigIntegerField()

addr=models.CharField( max_length=64)

class Publish(models.Model):

nid = models.AutoField(primary_key=True)

name=models.CharField( max_length=32)

city=models.CharField( max_length=32)

email=models.EmailField()

def __str__(self):

return self.name

class Book(models.Model):

nid = models.AutoField(primary_key=True)

title = models.CharField( max_length=32)

publishDate=models.DateField()

price=models.DecimalField(max_digits=5,decimal_places=2)

publish=models.ForeignKey(to="Publish",to_field="nid")

authors=models.ManyToManyField(to='Author',)

def __str__(self):

return self.title

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

二、自定义分页

当数据库中数据有很多,我们通常会在前端页面做分页展示。

分页的数据可以在前端页面实现,也可以在后端实现分页。

后端实现分页的原理就是每次只请求一页数据。

准备工作

我们使用脚本批量创建一些测试数据(将下面的代码保存到bulk_create.py文件中放到Django项目的根目录,直接执行即可。):

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

import os

if __name__ == "__main__":

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "about_orm.settings")

import django

django.setup()

from app01 import models

bulk_obj = (models.Publisher(name='第{}出版社'.format(i)) for i in range(300))

models.Publisher.objects.bulk_create(bulk_obj) #批量添加,注意写法

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

看下面几个版本的分页:

961ddebeb323a10fe0623af514929fc1.png

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

def publisher_list(request):

# 从URL中取当前访问的页码数

try:

current_page = int(request.GET.get('page'))

except Exception as e:

# 取不到或者页码数不是数字都默认展示第1页

current_page = 1

# 总数据量

total_count = models.Publisher.objects.count()

# 定义每页显示多少条数据

per_page = 10

# 计算出总页码数

total_page, more = divmod(total_count, per_page)

if more:

total_page += 1

# 定义页面上最多显示多少页码(为了左右对称,一般设为奇数)

max_show = 11

half_show = max_show // 2

# 计算一下页面显示的页码范围

if total_page <= max_show: # 总页码数小于最大显示页码数

page_start = 1

page_end = total_page

elif current_page + half_show >= total_page: # 右边越界

page_end = total_page

page_start = total_page - max_show

elif current_page - half_show <= 1: # 左边越界

page_start = 1

page_end = max_show

else: # 正常页码区间

page_start = current_page - half_show

page_end = current_page + half_show

# 数据索引起始位置

data_start = (current_page-1) * per_page

data_end = current_page * per_page

publisher_list = models.Publisher.objects.all()[data_start:data_end]

# 生成页面上显示的页码

page_html_list = []

page_html_list.append('

  • ')

# 加首页

first_li = '

首页'

page_html_list.append(first_li)

# 加上一页

if current_page == 1:

prev_li = '

«'

else:

prev_li = '

«'.format(current_page - 1)

page_html_list.append(prev_li)

for i in range(page_start, page_end + 1):

if i == current_page:

li_tag = '

{0}'.format(i)

else:

li_tag = '

{0}'.format(i)

page_html_list.append(li_tag)

# 加下一页

if current_page == total_page:

next_li = '

»'

else:

next_li = '

»'.format(current_page + 1)

page_html_list.append(next_li)

# 加尾页

page_end_li = '

尾页'.format(total_page)

page_html_list.append(page_end_li)

page_html_list.append('')

page_html = "".join(page_html_list)

return render(request, "publisher_list.html", {"publisher_list": publisher_list, "page_html": page_html})

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

961ddebeb323a10fe0623af514929fc1.png

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

class Pagination(object):

"""自定义分页(Bootstrap版)"""

def __init__(self, current_page, total_count, base_url, per_page=10, max_show=11):

"""

:param current_page: 当前请求的页码

:param total_count: 总数据量

:param base_url: 请求的URL

:param per_page: 每页显示的数据量,默认值为10

:param max_show: 页面上最多显示多少个页码,默认值为11

"""

try:

self.current_page = int(current_page)

except Exception as e:

# 取不到或者页码数不是数字都默认展示第1页

self.current_page = 1

# 定义每页显示多少条数据

self.per_page = per_page

# 计算出总页码数

total_page, more = divmod(total_count, per_page)

if more:

total_page += 1

self.total_page = total_page

# 定义页面上最多显示多少页码(为了左右对称,一般设为奇数)

self.max_show = max_show

self.half_show = max_show // 2

self.base_url = base_url

@property

def start(self):

return (self.current_page-1) * self.per_page

@property

def end(self):

return self.current_page * self.per_page

def page_html(self):

# 计算一下页面显示的页码范围

if self.total_page <= self.max_show: # 总页码数小于最大显示页码数

page_start = 1

page_end = self.total_page

elif self.current_page + self.half_show >= self.total_page: # 右边越界

page_end = self.total_page

page_start = self.total_page - self.max_show

elif self.current_page - self.half_show <= 1: # 左边越界

page_start = 1

page_end = self.max_show

else: # 正常页码区间

page_start = self.current_page - self.half_show

page_end = self.current_page + self.half_show

# 生成页面上显示的页码

page_html_list = []

page_html_list.append('

  • ')

# 加首页

first_li = '

首页'.format(self.base_url)

page_html_list.append(first_li)

# 加上一页

if self.current_page == 1:

prev_li = '

«'

else:

prev_li = '

«'.format(

self.base_url, self.current_page - 1)

page_html_list.append(prev_li)

for i in range(page_start, page_end + 1):

if i == self.current_page:

li_tag = '

{1}'.format(self.base_url, i)

else:

li_tag = '

{1}'.format(self.base_url, i)

page_html_list.append(li_tag)

# 加下一页

if self.current_page == self.total_page:

next_li = '

»'

else:

next_li = '

»'.format(

self.base_url, self.current_page + 1)

page_html_list.append(next_li)

# 加尾页

page_end_li = '

尾页'.format(self.base_url, self.total_page)

page_html_list.append(page_end_li)

page_html_list.append('')

return "".join(page_html_list)

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

961ddebeb323a10fe0623af514929fc1.png

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

def publisher_list(request):

# 从URL中取当前访问的页码数

current_page = int(request.GET.get('page'))

# 比len(models.Publisher.objects.all())更高效

total_count = models.Publisher.objects.count()

page_obj = Pagination(current_page, total_count, request.path_info)

data = models.Publisher.objects.all()[page_obj.start:page_obj.end]

page_html = page_obj.page_html()

return render(request, "publisher_list.html", {"publisher_list": data, "page_html": page_html})

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

再来一版django内置分页器的分页

961ddebeb323a10fe0623af514929fc1.png

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

from django.shortcuts import render

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

L = []

for i in range(999):

L.append(i)

def index(request):

current_page = request.GET.get('p')

paginator = Paginator(L, 10)

# per_page: 每页显示条目数量

# count: 数据总个数

# num_pages:总页数

# page_range:总页数的索引范围,如: (1,10),(1,200)

# page: page对象

try:

posts = paginator.page(current_page)

# has_next 是否有下一页

# next_page_number 下一页页码

# has_previous 是否有上一页

# previous_page_number 上一页页码

# object_list 分页之后的数据列表

# number 当前页

# paginator paginator对象

except PageNotAnInteger:

posts = paginator.page(1)

except EmptyPage:

posts = paginator.page(paginator.num_pages)

return render(request, 'index.html', {'posts': posts})

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

961ddebeb323a10fe0623af514929fc1.png

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

{% for item in posts %}

{{ item }}

{% endfor %}

[

48304ba5e6f9fe08f3fa1abda7d326ab.png](javascript:void(0)

你可能感兴趣的:(django,mysql分页)