1. 程式人生 > >Python自定義分頁程序

Python自定義分頁程序

當前頁 start itl ati doc line mod 防止 分頁

為了防止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>

  

Python自定義分頁程序