Python自定义分页组件

时间:2023-03-09 09:21:57
Python自定义分页组件

为了防止XSS即跨站脚本攻击,需要加上 safe

# 路由
from django.conf.urls import url
from django.contrib import admin
from mypaginator import views urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^hosts.html$', views.hosts),
] # 视图函数
def hosts(request):
"""创建测试数据"""
# for i in range(303):
# name = "c%s.com" % i
# port = i
# models.Host.objects.create(hostname=name,port=port)
# return HttpResponse("OK") # 默认每页显示10条数据
items_per_page = 10
# 前端请求的url:http://127.0.0.1:8001/hosts.html?page=2
current_page = int(request.GET.get('page'))
# x -> items_per_page*(x-1) ~ items_per_page*x
start_item = items_per_page*(current_page-1)
end_item = items_per_page*current_page
# 通过切片的形式从数据库中拿到对应页数的items
host_list = models.Host.objects.all()[start_item:end_item] page_str = """
<a href="hosts.html?page=1">1</a>
<a href="hosts.html?page=2">2</a>
<a href="hosts.html?page=3">3</a>
""" return render(request,'hosts.html',locals()) # 前端HTML
...
<div class="pagination">
{{ page_str|safe }}
</div>
...

  

自定义分页组件

# 路由

from django.conf.urls import url
from django.contrib import admin
from mypaginator import views urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^hosts.html$', views.hosts),
]

  

# models

from django.db import models

# Create your models here.

class Host(models.Model):
hostname = models.CharField(max_length=32)
port = models.CharField(max_length=10)

  

# 分页组件:  ..\paginator\utils\paginator.py

#!/usr/bin/python
# -*- coding:utf-8 -*- class Paginator(object):
def __init__(self,all_count,current_page,base_url,per_page=10,per_page_count=11):
"""
分页组件的初始化
:param all_count: 数据的总条数
:param current_page: 当前页码
:param base_url: 基础url
:param per_page: 每页显示的条目数
:param per_page_count: 显示的页码数
"""
self.all_count = all_count
self.current_page = current_page
self.base_url = base_url
self.per_page = per_page
self.per_page_count = per_page_count
# 计算得出真实的页码数
pager_count, remainder = divmod(self.all_count, self.per_page)
if 0 != remainder:
pager_count += 1
self.pager_count = pager_count
# 默认每次显示11个页码(除上一页、下一页、首页和尾页之外)并且让当前选择页码始终居中
self.half_per_page_count = int(self.per_page_count / 2) @property
def start(self):
"""
数据条目的起始索引
# x -> items_per_page*(x-1) ~ items_per_page*x
:return:
"""
return self.per_page * (self.current_page - 1) @property
def end(self):
"""
数据条目的结束索引
# x -> items_per_page*(x-1) ~ items_per_page*x
:return:
"""
return self.per_page * self.current_page @property
def page_html(self):
# 获取正确的开始页码和结束页码
# 判断真实的页码数是否超过 per_page_count
if self.pager_count > self.per_page_count:
# 如果当前页 < half_per_page_count
if self.current_page <= self.half_per_page_count:
pager_start = 1
pager_end = self.per_page_count
# 如果当前页码 大于 half_per_page_count 并且 小于 pager_count - half_per_page_count
elif self.current_page <= self.pager_count - self.half_per_page_count:
pager_start = self.current_page - self.half_per_page_count
pager_end = self.current_page + self.half_per_page_count
# 如果当前页码大于 pager_count - half_per_page_count
else:
pager_start = self.pager_count - self.per_page_count + 1
pager_end = self.pager_count
else:
pager_start = 1
pager_end = self.pager_count page_list = []
first_page = '<a href="{}?page=1">首页</a>'.format(self.base_url)
page_list.append(first_page)
if self.current_page > 1:
prev = '<a href="{}?page={}">上一页</a>'.format(self.base_url,self.current_page - 1)
else:
prev = '<a href="javascript:void(0)" disabled="true">上一页</a>'
page_list.append(prev) # 循环生成HTML
for i in range(pager_start, pager_end + 1):
if i == self.current_page:
tpl = '<a class="active" href="{}?page={}">{}</a>'.format(self.base_url,i, i)
else:
tpl = '<a href="{}?page={}">{}</a>'.format(self.base_url,i, i)
page_list.append(tpl) if self.current_page < self.pager_count:
nex = '<a href="{}?page={}">下一页</a>'.format(self.base_url,self.current_page + 1)
else:
nex = '<a href="javascript:void(0)" disabled="true">下一页</a>'.format(self.current_page + 1)
page_list.append(nex) last_page = '<a href="{}?page={}">尾页</a>'.format(self.base_url,self.pager_count)
page_list.append(last_page)
page_str = "".join(page_list)
return page_str

  

# 视图函数

from django.shortcuts import render,HttpResponse

# Create your views here.

from mypaginator import models
from utils.paginator import Paginator def hosts(request):
"""创建测试数据"""
# for i in range(303):
# name = "c%s.com" % i
# port = i
# models.Host.objects.create(hostname=name,port=port)
# return HttpResponse("OK") # 后端生成好页面HTML,然后返回给前端显示
_page_str = """
<a href="hosts.html?page=1">1</a>
<a href="hosts.html?page=2">2</a>
<a href="hosts.html?page=3">3</a>
"""
# 前端请求的url:http://127.0.0.1:8001/hosts.html?page=2
current_page = int(request.GET.get('page'))
# 首先获得数据总条数
all_count = models.Host.objects.all().count()
pager = Paginator(all_count=all_count,current_page=current_page,base_url=request.path_info)
# 通过切片的形式从数据库中拿到对应页数的items
host_list = models.Host.objects.all()[pager.start:pager.end]
page_str = pager.page_html
return render(request,'hosts.html',locals())

  

# 前端HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.mypagination a{
display: inline-block;
padding: 5px 8px;
background-color: darkslateblue;
margin: 5px;
color: white;
}
.mypagination a.active{
background-color: green;
}
</style>
</head>
<body>
<h1>主机列表</h1>
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>主机名</th>
<th>端口</th>
</tr>
</thead>
<tbody>
{% for row in host_list %}
<tr>
<td>{{ row.id }}</td>
<td>{{ row.hostname }}</td>
<td>{{ row.port }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="mypagination">
{{ page_str|safe }}
</div>
</body>
</html>