1. 程式人生 > >Python之路65-Django分頁、自定義分頁

Python之路65-Django分頁、自定義分頁

python

目錄

一、XSS

二、分頁1

三、分頁2

四、分頁3


一、XSS

有下面一段代碼,想將這段代碼中的字符串渲染到HTML頁面中,默認Django是不能這樣去操作的

views.py

def user_list(request):
    page_str = """
        <a href="/user_list/?p=1">1</a>
        <a href="/user_list/?p=2">2</a>
        <a href="/user_list/?p=3">3</a>
    """
    return render(request, "user_list.html", {"page_str": page_str})

user_list.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        {% for item in li %}
            {% include "li.html" %}
        {% endfor %}
    </ul>
    <div>
        {{ page_str }}
    </div>
</body>
</html>

li.html

<li>{{ item }}</li>

渲染後的頁面只能以字符串的形式顯示我們傳入的HTML代碼

Django認為這存在危險,可能會存在代碼被註入的可能,我們可以通過下面兩種方式解決

1.模板的方式

{{ page_str|safe }}

2.視圖方式

from django.utils.safestring import mark_safe

def user_list(request):
    page_str = """
        <a href="/user_list/?p=1">1</a>
        <a href="/user_list/?p=2">2</a>
        <a href="/user_list/?p=3">3</a>
    """
    page_str = mark_safe(page_str)
    return render(request, "user_list.html", {"page_str": page_str})



二、分頁1


urls.py

from django.conf.urls import url
from django.contrib import admin
from django.conf.urls import include
from app01 import views

urlpatterns = [
    url(r‘^admin/‘, admin.site.urls),
    url(r‘^user_list/‘, views.user_list),
]


views.py

from django.shortcuts import render
from django.shortcuts import HttpResponse
# Create your views here.
from django.urls import reverse

from django.utils.safestring import mark_safe

LIST = []
for i in range(109):
    LIST.append(i)


def user_list(request):
    current_page = request.GET.get("p", 1)
    current_page = int(current_page)
    start = (current_page - 1) * 10
    end = current_page * 10
    data = LIST[start:end]

    # 總個數
    all_count = len(LIST)
    # 取商、余數
    count, y = divmod(all_count, 10)
    
    if y:
        count += 1
        
    page_list = []
    
    for i in range(1, count+1):
        if i == current_page:
            temp = ‘<a class="page active" href="/user_list/?p=%s">%s</a>‘ % (i, i)
        else:
            temp = ‘<a class="page" href="/user_list/?p=%s">%s</a>‘ % (i, i)
        page_list.append(temp)

    page_str = "".join(page_list)
    page_str = mark_safe(page_str)
    return render(request, "user_list.html", {"li": data, "page_str": page_str})


user_list.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .pagination .page{
            display: inline-block;
            padding: 5px;
            background-color: cyan;
            margin: 5px;
        }
        .pagination .page.active{
            background-color: brown;
            color: black;
        }
    </style>
</head>
<body>
    <ul>
        {% for item in li %}
            {% include "li.html" %}
        {% endfor %}
    </ul>
    <div class="pagination">
        {{ page_str }}
    </div>
</body>
</html>

三、分頁2


views.py

from django.shortcuts import render
from django.shortcuts import HttpResponse
# Create your views here.
from django.urls import reverse

from django.utils.safestring import mark_safe

LIST = []
for i in range(1009):
    LIST.append(i)


def user_list(request):
    current_page = request.GET.get("p", 1)
    # 當前頁數
    current_page = int(current_page)

    per_page_count = 10

    start = (current_page - 1) * per_page_count
    end = current_page * per_page_count
    data = LIST[start:end]

    # 總個數
    all_count = len(LIST)
    # 取商、余數
    total_count, y = divmod(all_count, per_page_count)
    if y:
        total_count += 1
    page_list = []

    pager_num = 11

    if total_count < pager_num:
        start_index = 1
        end_index = total_count + 1
    else:
        if current_page <= (pager_num+1)/2:
            start_index = 1
            end_index = pager_num + 1
        else:
            start_index = current_page - (pager_num-1)/2
            end_index = current_page + (pager_num+1)/2
            if (current_page + (pager_num-1)/2) > total_count:
                end_index = total_count + 1
                start_index = total_count - pager_num + 1

    if current_page == 1:
        prev = ‘<a class="page" href="#">上一頁</a>‘
    else:
        prev = ‘<a class="page" href="/user_list/?p=%s">上一頁</a>‘ % (current_page - 1)
    page_list.append(prev)

    for i in range(int(start_index), int(end_index)):
        if i == current_page:
            temp = ‘<a class="page active" href="/user_list/?p=%s">%s</a>‘ % (i, i)
        else:
            temp = ‘<a class="page" href="/user_list/?p=%s">%s</a>‘ % (i, i)
        page_list.append(temp)

    if current_page == total_count:
        nex = ‘<a class="page" href="#">下一頁</a>‘
    else:
        nex = ‘<a class="page" href="/user_list/?p=%s">下一頁</a>‘ % (current_page + 1)
    page_list.append(nex)

    jump = """
    <input type=‘text‘ /><a id=‘ii1‘ onclick=‘jumpTo(this, "/user_list/?p=");‘>GO</a>
    <script>
        function jumpTo(ths, base){
            var val = ths.previousSibling.value;
            location.href = base + val;
        }
    </script>
    """
    page_list.append(jump)

    page_str = "".join(page_list)
    page_str = mark_safe(page_str)
    return render(request, "user_list.html", {"li": data, "page_str": page_str})


user_list.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .pagination .page{
            display: inline-block;
            padding: 5px;
            background-color: cyan;
            margin: 5px;
        }
        .pagination .page.active{
            background-color: brown;
            color: black;
        }
    </style>
</head>
<body>
    <ul>
        {% for item in li %}
            {% include "li.html" %}
        {% endfor %}
    </ul>
    <div class="pagination">
        {{ page_str }}
    </div>
</body>
</html>

四、分頁3


urls.py

from django.conf.urls import url
from django.contrib import admin
from django.conf.urls import include
from app01 import views

urlpatterns = [
    url(r‘^admin/‘, admin.site.urls),
    url(r‘^user_list/‘, views.user_list),
]


views.py

from django.shortcuts import render
from django.shortcuts import HttpResponse
# Create your views here.
from django.urls import reverse

from utils import pagination

LIST = []
for i in range(1009):
    LIST.append(i)


def user_list(request):
    current_page = request.GET.get("p", 1)
    current_page = int(current_page)

    page_obj = pagination.Page(current_page, len(LIST))
    data = LIST[page_obj.start:page_obj.end]
    page_str = page_obj.page_str("/user_list/")
    return render(request, "user_list.html", {"li": data, "page_str": page_str})


在工程目錄創建目錄utils,然後在此目錄中創建pagination.py文件

pagination.py

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
# Author: JiaChen

from django.utils.safestring import mark_safe


# 封裝分頁模塊
class Page(object):

    def __init__(self, current_page, data_count, per_page_count=10, pager_num=7):
        self.current_page = current_page
        self.data_count = data_count
        self.per_page_count = per_page_count
        self.pager_num = pager_num

    @property
    def start(self):
        return (self.current_page - 1) * self.per_page_count

    @property
    def end(self):
        return self.current_page * self.per_page_count

    @property
    def total_count(self):
        v, y = divmod(self.data_count, self.per_page_count)
        if y:
            v += 1
        return v

    def page_str(self, base_url):
        page_list = []
        if self.total_count < self.pager_num:
            start_index = 1
            end_index = self.total_count + 1
        else:
            if self.current_page <= (self.pager_num + 1) / 2:
                start_index = 1
                end_index = self.pager_num + 1
            else:
                start_index = self.current_page - (self.pager_num - 1) / 2
                end_index = self.current_page + (self.pager_num + 1) / 2
                if (self.current_page + (self.pager_num - 1) / 2) > self.total_count:
                    end_index = self.total_count + 1
                    start_index = self.total_count - self.pager_num + 1

        if self.current_page == 1:
            prev = ‘<a class="page" href="#">上一頁</a>‘
        else:
            prev = ‘<a class="page" href="%s?p=%s">上一頁</a>‘ % (base_url, self.current_page - 1)
        page_list.append(prev)

        for i in range(int(start_index), int(end_index)):
            if i == self.current_page:
                temp = ‘<a class="page active" href="%s?p=%s">%s</a>‘ % (base_url, i, i)
            else:
                temp = ‘<a class="page" href="%s?p=%s">%s</a>‘ % (base_url, i, i)
            page_list.append(temp)

        if self.current_page == self.total_count:
            nex = ‘<a class="page" href="#">下一頁</a>‘
        else:
            nex = ‘<a class="page" href="%s?p=%s">下一頁</a>‘ % (base_url, self.current_page + 1)
        page_list.append(nex)

        jump = """
        <input type=‘text‘ /><a id=‘ii1‘ onclick=‘jumpTo(this, "%s?p=");‘>GO</a>
        <script>
            function jumpTo(ths, base){
                var val = ths.previousSibling.value;
                location.href = base + val;
            }
        </script>
        """ % base_url
        page_list.append(jump)
        page_str = "".join(page_list)
        page_str = mark_safe(page_str)
        return page_str


user_list.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .pagination .page{
            display: inline-block;
            padding: 5px;
            background-color: cyan;
            margin: 5px;
        }
        .pagination .page.active{
            background-color: brown;
            color: black;
        }
    </style>
</head>
<body>
    <ul>
        {% for item in li %}
            {% include "li.html" %}
        {% endfor %}
    </ul>
    <div class="pagination">
        {{ page_str }}
    </div>
</body>
</html>


本文出自 “八英裏” 博客,請務必保留此出處http://5921271.blog.51cto.com/5911271/1929399

Python之路65-Django分頁、自定義分頁