from django.utils.safestring import mark_safe
class Paging:
def __init__(self,current_page_number,total_count,per_page_count=10,page_number_show=7,recv_data=None):
"""
:param current_page_number: 當前頁碼
:param total_count: 總數據量
:param per_page_count: 每頁顯示條數
:param page_number_show: 總顯示頁碼
:param start_page_number: 起始頁碼
:param end_page_number: 結束頁碼
"""
self.recv_data = recv_data # 用作保存查詢條件,只做分頁不做查詢時可以忽略
try:
current_page_number = int(current_page_number)
# 驗證頁碼是否是數字
except Exception:
current_page_number = 1
a, b = divmod(total_count, per_page_count)
# divmod:返回一個包含商和餘數的元組
if b:
total_page_count = a + 1
# 如果餘數不爲0顯示總頁碼爲商加1
else:
total_page_count = a
# 如果餘數爲0則商就是總頁碼
# total_page_count 總頁碼數
if current_page_number <= 0:
current_page_number = 1
# 當頁碼小於0時默認顯示第1頁
if current_page_number >= total_page_count:
current_page_number = total_page_count
# 如果當前頁碼大於總頁碼默認顯示最後一頁
half_number = page_number_show // 2
# half_number用作計算起始頁碼和結束頁碼
start_page_number = current_page_number - half_number
# 起始頁碼
end_page_number = current_page_number + half_number + 1
# 結束頁碼
if start_page_number <= 0:
# 防止起始頁碼變爲負數
start_page_number = 1
end_page_number = page_number_show + 1
if end_page_number >= total_page_count:
# 防止結束頁碼超出總頁碼數
start_page_number = total_page_count - page_number_show + 1
end_page_number = total_page_count + 1
if total_page_count < page_number_show:
# 防止數據不足填充全部顯示頁碼
start_page_number = 1
end_page_number = total_page_count + 1
self.current_page_number = current_page_number
self.per_page_count = per_page_count
self.total_page_count = total_page_count
self.start_page_number = start_page_number
self.end_page_number = end_page_number
@property
def start_data_number(self):
# 數據切片起始值
return (self.current_page_number - 1) * self.per_page_count
@property
def end_data_number(self):
# 數據切片結束值
return self.current_page_number*self.per_page_count
def page_html_func(self):
# 生成html
page_html = """
<nav aria-label="Page navigation">
<ul class="pagination">
"""
self.recv_data['page'] = 1
first_page = f"""
<li>
<a href="?{self.recv_data.urlencode()}" aria-label="Previous">
<span aria-hidden="true">首頁</span>
</a>
</li>"""
page_html += first_page
self.recv_data['page'] = self.current_page_number - 1
previous_page = f"""
<li>
<a href="?{self.recv_data.urlencode()}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>"""
page_html += previous_page
for i in range(self.start_page_number,self.end_page_number):
self.recv_data['page'] = i
if i == self.current_page_number:
page_html += f'<li class="active"><a href="?{self.recv_data.urlencode()}">{i}</a></li>'
else:
page_html += f"""<li><a href="?{self.recv_data.urlencode()}">{i}</a></li>"""
self.recv_data['page'] = self.current_page_number + 1
next_page = f"""
<li>
<a href="?{self.recv_data.urlencode()}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
"""
page_html += next_page
self.recv_data['page'] = self.total_page_count
last_page = f"""
<li>
<a href="?{self.recv_data.urlencode()}" aria-label="Previous">
<span aria-hidden="true">尾頁</span>
</a>
</li>"""
page_html += last_page
page_html += """
</ul>
</nav>
"""
return mark_safe(page_html)
views.py:
def index(request):
recv_data = copy.copy(request.GET) # 用作保存查詢條件
current_page_number = request.GET.get('page') # 當前頁碼
all_customers = models.Customer.objects.all() # 全部數據
total_count = all_customers.count() # 全部數據量
page_obj = Paging(current_page_number,total_count,per_page_count,page_number_show,recv_data)
all_customers = all_customers[page_obj.start_data_number:page_obj.end_data_number] # 對數據進行切片
page_html = page_obj.page_html_func() # 獲得頁碼html
return render(request, 'index.html', {
'all_customers ': all_customers ,
'page_html': page_html})
index.html
{% for objin all_customers %}
{ customer.name }}
{% endfor %}
{{ page_html }}