1. 程式人生 > >Django自定義分頁,實現paginator缺失的功能

Django自定義分頁,實現paginator缺失的功能

有不少初學Django的朋友經常抱怨,在網上搜了一大堆教程,各種自定也分頁的方法對新手一點都不友好,很難看懂。那今天我來寫一個相對容易看懂的教程吧。

django內建paginator分頁器雖然用起來是很簡單,但是功能也很簡單。一旦資料多起來,就會把頁碼分列成好幾行,極不美觀。那麼要想自己限定當前最多顯示前後多少頁碼,那要不就是重寫paginator中的一些方法,或者用Listview。

但今天我更推薦初學者自己嘗試自定義一個分頁方法:

LIST = []
for i in range(209):
    LIST.append(i)
#這裡就不用資料庫的資料了,用個列表來舉例,假設列表裡有209條資料
def url_list(request): #url_list是我臨時起的檢視名稱,大家按照自己urls.py裡面對應url寫就行 current_page = request.GET.get('p',1) current_page = int(current_page) #獲取當前頁碼 total_count = len(LIST) #資料總長度 per_page = 10 #每頁顯示多少條資料 max_page = 11 #頁面上始終保持最多顯示多少頁碼 start = (current_page-1) * per_page end = current_page * per_page #資料展示的起始點和結束點
total_page,y = divmod(total_count,per_page) if y: total_page += 1 #divmod()方法要是不知道就百度吧,用來整除和取餘數用的。也就是假設每頁10條資料, #那麼209條資料可以分多少頁,那麼用209整除10就行了,要是有餘數,就加一頁, #餘數也就是'y',總頁數是'total_page' if current_page > total_page: current_page = total_page #如果當前頁碼比總頁數還大,那就限定當前頁等於總頁數,不然你會有無窮的頁碼
if max_page > total_page: max_page = total_page #如果最大頁碼也大於總頁數,那就以說明資料量很少,分不足11頁,那就讓分頁範圍是總頁數 half_max_page = max_page -1// 2 #half_max_page代表當前頁碼的前後各有多少頁 start_page = current_page - half_max_page end_page = current_page + half_max_page #起始頁和結束頁 if start_page <= 1: start_page = 1 end_page = max_page #如果起始頁比1還小,那就定起始頁顯示為1,結束頁為最大顯示頁數11,也就是【1、2、 34567891011】,否則會出現負數頁數顯示在頁面上 if end_page > total_page: end_page = total_page start_page = total_page - max_page +1 #如果結束頁比總頁數還大,那就定結束頁為最後一頁,起始頁為總頁數前10頁,比如說總頁數是20,那就是【10、11、12、13、14、15、16、17、18、19、20】,這是防止出現20頁以後還出現更大的頁碼 data = LIST[start:end] #這裡就基本設定好了每頁對應顯示哪幾條資料了,data是用來接收的變數,最後用來渲染的 page_str = [] #先建立一個空列表,用來接收等下要插入的html標籤,最後渲染到模板裡 page_str.append('<div class="page"><a href="/url_list/?p=1">首頁</a></div>') if current_page <= 1: page_str.append('<div class="page hide"><a href="/url_list/?p=%s">上一頁</a></div>'%(current_page-1)) else: page_str.append('<div class="page"><a href="/url_list/?p=%s">上一頁</a></div>'%(current_page-1)) #如果當前頁是第一頁,那就不存在“上一頁”的按鈕了 for i in range(start_page,end_page): if i == current_page: temp = '<div class="page active"><a href="/url_list/?p=%s">%s</a></div>' %(i,i) else: temp = '<div class="page"><a href="/url_list/?p=%s">%s</a></div>' %(i,i) page_str.append(temp) #重點來了,這裡的range(start_page,end_page)就是上面我們自己通過計算的出來的前後分頁 if current_page >= total_page: page_str.append('<div class="page hide"><a href="/url_list/?p=%s">下一頁</a></div>'%(current_page+1)) else: page_str.append('<div class="page"><a href="/url_list/?p=%s">下一頁</a></div>'%(current_page+1)) page_str.append('<div class="page"><a href="/url_list/?p=%s">尾頁</a></div>'%(total_page)) page_html = "".join(page_str) #最後一定要拼接成字串,再渲染,不然會出現很多類似'['的符號在網頁上,你懂的 return render(request,'url_list.html',{'data':data,'page_html':page_html})

還有在templates裡的:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
    .page{
        margin: 5px;
        background-color: pink;
        float: left
    }
    .active{
        background-color: blue
    }
    .hide{
        display: none
    }
    </style>
</head>
<body>
    <ul>
        {% for i in data %}
        <li>{{i}}</li>
        {% endfor %}
    </ul>
    {{page_html|safe}}

</body>
</html>

這樣的大功告成了,你完全可以先把程式碼複製進去,自己試一下。至於網頁的樣式,完全是可以自己自定義的。

注意事項:

另外,其實像這種分頁功能,理解了原理就行了,你不可能以後工作的時候動不動就幾十行程式碼就為了個分頁功能。這裡給大家推薦一個我本人自己常用的“輪子”:EasyPage,只需要設定5各引數,分頁想怎麼設定就怎麼設定,

原理和上面的程式碼一樣,只是我自己封裝成class了,用起來方便許多。