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)

  

# 分页组件:  ..paginatorutilspaginator.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>

  

作者:Standby一生热爱名山大川、草原沙漠,还有妹子
出处:http://www.cnblogs.com/standby/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

原文地址:https://www.cnblogs.com/standby/p/7667152.html