自定义分页

简单例子: 

urls.py:

from django.contrib import admin
from django.urls import path
from django.conf.urls import url,include
from app01 import views
urlpatterns = [

    url(r'^user_list/',views.user_list),
]

 先固定写死数据:view.py:

LIST = []
for i in range(100):
    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]
    return render(request,'user_list.html',{'li':data})

 

user_item.py

<!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>
        <a href="/user_list/?p=1">1</a>
        <a href="/user_list/?p=2">2</a>
        <a href="/user_list/?p=3">3</a>
    </div>
</body>
</html>

显示效果:

我们都知道后台穿过来的是一个字符串,如果我们把那些a标签从后台传过来,那会是什么样的呢?

views.py:

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]
    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',{'li':data})
    return render(request,'user_list.html',{'page_str':page_str,'li':data})

 

 html.py:

<div>
        {{ page_str }}
</div>

 

显示效果:

这里可以引入一个知识:XSS攻击:即评论,输入框等输入一些脚本,for循环。

如果想要显示的话:

 第一种方法:

{{ page_str|safe }}

 第二种方法:

from django.utils.safestring import mark_safe
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)

 

 

分页1.0版本:使用固定的列表数据,然后获得页数,

views.py:

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)

    
    return render(request,'user_list.html',{'page_str':page_str,'li':data})
View Code

html文件:

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

 显示效果:

 上面的分页代码我们在数据少的时候将就一下,但是如果一旦我们的数据多了,那我们如果一下子把所有的页数都显示在html中,那显然是不合适的,那我们应该要隐藏多的页数

那我们需要该for循环,显示当前页的前五个和后五个,来我们改写一些views里面的函数:

 1 def user_list(request):
 2     current_page = request.GET.get('p',1)
 3     current_page = int(current_page)
 4     page_size = 10#页面一次显示多少条数据
 5     page_num=11#页面显示的页数
 6     start = (current_page-1)*page_size
 7     end = current_page * page_size
 8     data = LIST[start:end]
 9 
10     all_count = len(LIST)
11     count,y = divmod(all_count,page_size)
12     if y:
13         count+=1
14 
15     page_list = []
16     if count <= 11:
17         start_index = 1
18         end_index = count+1
19     elif count > 11:
20         if current_page <= (page_num+1)/2:
21             start_index = 1
22             end_index = page_num + 1
23         elif (current_page+(page_num-1)/2) > count :
24             start_index = count-page_num+1
25             end_index = count + 1
26         else:
27             start_index = current_page - (page_num-1)/2
28             end_index = current_page + (page_num+1)/2
29     if current_page != 1:
30         prev_page = '<a class="page" href="/user_list/?p=%s">上一页</a>' % (current_page-1)
31         page_list.append(prev_page)
32     for i in range(int(start_index),int(end_index)):
33         if i == current_page:
34             temp = '<a class="page active" href="/user_list/?p=%s">%s</a>' % (i, i)
35         else:
36             temp = '<a class="page" href="/user_list/?p=%s">%s</a>' %(i,i)
37         page_list.append(temp)
38     if current_page != count:
39         after_page = '<a class="page" href="/user_list/?p=%s">下一页</a>' % (current_page + 1)
40         page_list.append(after_page)
41 
42     jump = '''
43     <input type="text" /><a onclick='jumpTo(this,"/user_list/?p=");'>GO</a>
44     <script>
45         function jumpTo(ths,base){
46             var val = ths.previousSibling.value;
47             location.href = base+val;
48         }
49     </script>
50     '''
51     page_list.append(jump)
52     page_str = "".join(page_list)
53 
54     #return render(request,'user_list.html',{'li':data})
55     return render(request,'user_list.html',{'page_str':page_str,'li':data})

 

效果显示:这样就实现了上一页下一页,跳转,根据当前页数的不同显示不一样的页码

我们再把这个分页功能封装成一个Page类,以后就可以通过类方法来生成分页:

 1 class Page(object):
 2     def __init__(self,current_page,data_count,page_size=10,page_num=11):
 3         self.current_page = current_page
 4         self.data_count = data_count
 5         self.page_size = page_size
 6         self.page_num = page_num
 7     @property
 8     def start(self):
 9         return (self.current_page-1)*self.page_size
10 
11     @property
12     def end(self):
13         return self.current_page * self.page_size
14 
15     @property
16     def allCount(self):
17         count, y = divmod(self.data_count, self.page_size)
18         if y:
19             count += 1
20         return count
21 
22     def pageList(self,count,base_url):
23         page_list = []
24         if count <= 11:
25             start_index = 1
26             end_index = count + 1
27         elif count > 11:
28             if self.current_page <= (self.page_num + 1) / 2:
29                 start_index = 1
30                 end_index = self.page_num + 1
31             elif (self.current_page + (self.page_num - 1) / 2) > count:
32                 start_index = count - self.page_num + 1
33                 end_index = count + 1
34             else:
35                 start_index = self.current_page - (self.page_num - 1) / 2
36                 end_index = self.current_page + (self.page_num + 1) / 2
37         if self.current_page != 1:
38             prev_page = '<a class="page" href="%s?p=%s">上一页</a>' % (base_url,self.current_page - 1)
39             page_list.append(prev_page)
40         for i in range(int(start_index), int(end_index)):
41             if i == self.current_page:
42                 temp = '<a class="page active" href="%s?p=%s">%s</a>' % (base_url,i, i)
43             else:
44                 temp = '<a class="page" href="%s?p=%s">%s</a>' % (base_url,i, i)
45             page_list.append(temp)
46         if self.current_page != count:
47             after_page = '<a class="page" href="%s?p=%s">下一页</a>' % (base_url,self.current_page + 1)
48             page_list.append(after_page)
49 
50         jump = '''
51             <input type="text" /><a onclick='jumpTo(this,"%s?p=");'>GO</a>
52             <script>
53                 function jumpTo(ths,base){
54                     var val = ths.previousSibling.value;
55                     location.href = base+val;
56                 }
57             </script>
58             ''' % (base_url)
59         page_list.append(jump)
60         return page_list
View Code

 然后创建一个utils,把分页类放在里面,用的时候调用就可以了

调用分页类:

from utils.pagination import Page
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 = Page(current_page,len(LIST))

    data = LIST[ page.start : page.end ]

    count = page.allCount

    page_list = page.pageList(count,'/user_list/')

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