Django自定義分頁,實現paginator缺失的功能
阿新 • • 發佈:2019-02-18
有不少初學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、
3、4、5、6、7、8、9、10、11】,否則會出現負數頁數顯示在頁面上
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了,用起來方便許多。