日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

自定义分页(模块化)

發(fā)布時(shí)間:2025/7/14 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自定义分页(模块化) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

自定義分頁(yè)

1、目的&環(huán)境準(zhǔn)備

目的把分頁(yè)寫成一個(gè)模塊的方式然后在需要分頁(yè)的地方直接調(diào)用模塊就行了。

環(huán)境準(zhǔn)備Django中生成一個(gè)APP并且注冊(cè),配置URL&Views

配置URL

from django.conf.urls import url from django.contrib import admin from app01 import viewsurlpatterns = [url(r'^admin/', admin.site.urls),url(r'^user_list/',views.user_list), ]

注冊(cè)APP

INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','app01', ]

配置models

from __future__ import unicode_literalsfrom django.db import models# Create your models here.class UserList(models.Model):username = models.CharField(max_length=32)age = models.IntegerField()

2、分析

分頁(yè)在基本上行所有的大型網(wǎng)站中都是需要的,比如博客園的分頁(yè),當(dāng)我們查詢的時(shí)候或查看的時(shí)候他有很多博文,難道他是一下把所有的博文都給我們返回的嗎?當(dāng)然不是:如下圖

我們可以根據(jù)提示來(lái)點(diǎn)擊上一頁(yè)和下一頁(yè)或者點(diǎn)擊我們想要查看的頁(yè)面,然后顯示我們要查看的博文鏈接!而不是一下把所有的博文給顯示出來(lái),這樣即節(jié)省流量又能改善用戶體驗(yàn)。

3、逐步完善分頁(yè)代碼

首先咱們先創(chuàng)建500條數(shù)據(jù)(之前不要忘記生成數(shù)據(jù)庫(kù)),在第一訪問(wèn)時(shí)設(shè)置下就OK

3.1、配置views創(chuàng)建數(shù)據(jù)

#/usr/bin/env python #-*- coding:utf-8 -*-from django.shortcuts import render from django.shortcuts import HttpResponse import models # Create your views here.def user_list(request):for i in range(500):dic = {'username': 'name_%d' % i, 'age': i}models.UserList.objects.create(**dic)return HttpResponse('OK')

3.2、配置html顯示數(shù)據(jù)并通過(guò)views獲取數(shù)據(jù)顯示

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><table>{% for line in result %}<tr><td>{{ line.username }}</td><td>{{ line.age }}</td></tr>{% endfor %}</table><div>{{ pager_str|safe }}</div></body></html>

views

def user_list(request):result = models.UserList.objects.all()return render(request,'user_list.html',{'result':result})

這樣,前端可以正常顯示咱們?nèi)サ臄?shù)據(jù)了,但是一下子把所有的數(shù)據(jù)都取出來(lái)了。不是咱們想要的結(jié)果。

3.3、取指定的條數(shù)

比如我想取前10條怎么取呢?

def user_list(request):result = models.UserList.objects.all()[0:10]return render(request,'user_list.html',{'result':result})

那我讓[0:10]動(dòng)態(tài)起來(lái)就可以了!開(kāi)始和結(jié)尾。

3.4、每頁(yè)顯示10條數(shù)據(jù)

向用戶獲取頁(yè)數(shù),我們可以配置URL在URL中有兩種方式查詢直接在URL中配置正則,然后在views里可以通過(guò)參數(shù)來(lái)獲取用戶傳過(guò)來(lái)的值,

也可以通過(guò)?a=9 &b=10 這樣在Veiws函數(shù)里可以通過(guò)request.GET['a']取值了,并且可以設(shè)置默認(rèn)值request.GET.get('a',0)

def user_list(request):current_page = request.GET.get('page')print current_pageresult = models.UserList.objects.all()[0:10]return render(request,'user_list.html',{'result':result})

測(cè)試:

? ?這里的問(wèn)號(hào)是通過(guò)get的方式向后端發(fā)送數(shù)據(jù),我們也可以修改form表單中method改為GET,那么數(shù)據(jù)訪問(wèn)的時(shí)候就是通過(guò)GET方式向后端提交數(shù)據(jù)的,當(dāng)點(diǎn)擊form表單提交數(shù)據(jù)的時(shí)候,form里的內(nèi)容會(huì)自動(dòng)添加到瀏覽器的URL中以上面的格式!

雖然POST和GET都可以向后端提交數(shù)據(jù)但是規(guī)定:GET一般用來(lái)查詢使用,POST一般用來(lái)提交修改數(shù)據(jù)使用,根據(jù)實(shí)際的情況來(lái)定!

看下面的代碼:

def user_list(request):current_page = request.GET.get('page',1)print current_pagestart = 0 #10 20 (current_page-1)*10end = 10 #20 30 current_page*10result = models.UserList.objects.all()[start:end]return render(request,'user_list.html',{'result':result})

我們現(xiàn)在讓start & end 動(dòng)態(tài)起來(lái)頁(yè)面動(dòng)態(tài)起來(lái)是不是就更好了?

def user_list(request):current_page = request.GET.get('page',1)current_page = int(current_page)start = (current_page-1)*10 #10 20 (current_page-1)*10end = current_page*10 #20 30 current_page*10result = models.UserList.objects.all()[start:end]return render(request,'user_list.html',{'result':result})

然后打開(kāi)網(wǎng)頁(yè)測(cè)試下,修改page的值來(lái)看下顯示效果:

http://127.0.0.1:8000/user_list/?page=2

http://127.0.0.1:8000/user_list/?page=3

http://127.0.0.1:8000/user_list/?page=4 ?

分頁(yè)代碼整理

我們通過(guò)把上面的代碼整理一下整理到函數(shù)或類里下次使用的時(shí)候直接調(diào)用類或者函數(shù)即可。

#/usr/bin/env python #-*- coding:utf-8 -*-from django.shortcuts import render from django.shortcuts import HttpResponse import models # Create your views here.class Pager(object):def __init__(self,current_page):self.current_page = int(current_page)#把方法偽造成屬性(1) @propertydef start(self):return (self.current_page-1)*10@propertydef end(self):return self.current_page*10def user_list(request):current_page = request.GET.get('page',1)page_obj = Pager(current_page)#把方法改造成屬性(2),這樣在下面調(diào)用方法的時(shí)候就不需要加括號(hào)了result = models.UserList.objects.all()[page_obj.start:page_obj.end]return render(request,'user_list.html',{'result':result})

2、生成按鈕頁(yè)

上面的功能實(shí)現(xiàn)了分頁(yè)現(xiàn)在,我們是不是可以在下面生成一堆的按鈕來(lái)讓用戶點(diǎn)擊,而不是在瀏覽器中輸入!

先看下如果咱們手動(dòng)寫的話!

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><table>{% for line in result %}<tr><td>{{ line.username }}</td><td>{{ line.age }}</td></tr>{% endfor %}</table><div><a href="/user_list/?page=1">1</a><a href="/user_list/?page=2">2</a><a href="/user_list/?page=3">3</a><a href="/user_list/?page=4">4</a><a href="/user_list/?page=5">5</a></div></body></html>

如下圖:

?

目的是為了實(shí)現(xiàn)左側(cè)的效果,但是咱們不可能手寫吧?所以應(yīng)該在后臺(tái)創(chuàng)建,這個(gè)是不是就是總共有多少頁(yè)?

需求分析:

每頁(yè)顯示10條數(shù)據(jù)

共500條數(shù)據(jù)就是50頁(yè),那有501條數(shù)據(jù)呢?是多少頁(yè)是51頁(yè)。

可以通過(guò)divmod(500,10),他會(huì)的到一個(gè)元組,第一個(gè)值是值,第二個(gè)值是余數(shù),我們就通過(guò)判斷他是否有余數(shù)來(lái)判斷是否是整頁(yè),如果有余數(shù)在整頁(yè)基礎(chǔ)加1即可!

我們獲取了所有的頁(yè)數(shù)之后可以吧他返回在前端生成,但是這樣我們后端做了分頁(yè)之后前端是不是也做了分頁(yè)操作?

我們可以在后端生成一個(gè)大字符串然后把他返回給前端(拼接的URL)

#/usr/bin/env python #-*- coding:utf-8 -*-from django.shortcuts import render from django.shortcuts import HttpResponse import models # Create your views here.class Pager(object):def __init__(self,current_page):self.current_page = int(current_page)#把方法偽造成屬性(1) @propertydef start(self):return (self.current_page-1)*10@propertydef end(self):return self.current_page*10def user_list(request):current_page = request.GET.get('page',1)page_obj = Pager(current_page)#吧方法未造成屬性(2),這樣在下面調(diào)用方法的時(shí)候就不需要加括號(hào)了result = models.UserList.objects.all()[page_obj.start:page_obj.end]all_item = models.UserList.objects.all().count()all_page,div = divmod(all_item,10)if div > 0:all_page +=1pager_str = ""for i in range(1,all_page+1):#每次循環(huán)生成一個(gè)標(biāo)簽temp = '<a href="/user_list/?page=%d">%d</a>' %(i,i,)#把標(biāo)簽拼接然后返回給前端pager_str += tempreturn render(request,'user_list.html',{'result':result,'pager_str':pager_str})

前端配置:

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><table>{% for line in result %}<tr><td>{{ line.username }}</td><td>{{ line.age }}</td></tr>{% endfor %}</table><div>{{ pager_str }}</div></body></html>

但是有個(gè)問(wèn)題如下圖:

這個(gè)是什么問(wèn)題導(dǎo)致的呢?

咱們?cè)谥暗奈恼聦W(xué)過(guò)一個(gè)CSRF跨站請(qǐng)求偽造的安全設(shè)置,這里還有一個(gè)值得說(shuō)的安全就是XSS攻擊:

XSS攻擊:跨站腳本攻擊(Cross Site Scripting),為不和層疊樣式表(Cascading Style Sheets, CSS)的縮寫混淆,故將跨站腳本攻擊縮寫為XSS。

XSS是一種經(jīng)常出現(xiàn)在web應(yīng)用中的計(jì)算機(jī)安全漏洞,它允許惡意web用戶將代碼植入到提供給其它用戶使用的頁(yè)面中。比如這些代碼包括HTML代碼和客戶端腳本。攻擊者利用XSS漏洞旁路掉訪問(wèn)控制——例如同源策略(same origin policy)。這種類型的漏洞由于被黑客用來(lái)編寫危害性更大的網(wǎng)絡(luò)釣魚(yú)(Phishing)攻擊而變得廣為人知。對(duì)于跨站腳本攻擊,黑客界共識(shí)是:跨站腳本攻擊是新型的“緩沖區(qū)溢出攻擊“,而JavaScript是新型的“ShellCode”。

咱們上面看到的內(nèi)容就是Django為了防止這樣的情況產(chǎn)生而設(shè)置的機(jī)制,例子如下:

如果,寫的簡(jiǎn)單的script可以被保存為HTML標(biāo)簽的話那么?只要有人打開(kāi)這個(gè)頁(yè)面都會(huì)提示一個(gè)信息,這樣是不是不安全,這個(gè)是小的說(shuō)的!

如果說(shuō)這里是一個(gè)獲取Cookie然后發(fā)送到指定服務(wù)器然后服務(wù)器可以通過(guò)cookie訪問(wèn)你的個(gè)人信息是不是就可怕了?!

?那么怎么解決這個(gè)問(wèn)題呢?可以通過(guò)模板語(yǔ)言的一個(gè)函數(shù)來(lái)告訴Django這個(gè)是安全的:加一個(gè)safe (在文章的后面還有一種方法在后端標(biāo)記他是安全的)

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><table>{% for line in result %}<tr><td>{{ line.username }}</td><td>{{ line.age }}</td></tr>{% endfor %}</table><div>{{ pager_str|safe }}</div></body></html>

效果如下:

這樣全顯示出來(lái)了,不是很好,最好顯示11頁(yè)然后,當(dāng)用戶點(diǎn)擊第6頁(yè)的時(shí)候,這個(gè)6永遠(yuǎn)在中間!所以我們也要讓頁(yè)碼動(dòng)態(tài)起來(lái)!

#/usr/bin/env python #-*- coding:utf-8 -*-from django.shortcuts import render from django.shortcuts import HttpResponse import models # Create your views here.class Pager(object):def __init__(self,current_page):self.current_page = int(current_page)#把方法偽造成屬性(1) @propertydef start(self):return (self.current_page-1)*10@propertydef end(self):return self.current_page*10def page_str(self,all_item,base_url):all_page, div = divmod(all_item, 10)if div > 0:all_page += 1pager_str = ""#默認(rèn)可以看到的頁(yè)碼11個(gè)start = self.current_page - 5end = self.current_page + 6#把頁(yè)面動(dòng)態(tài)起來(lái)傳入起始和結(jié)束for i in range(start, end):#判斷是否為當(dāng)前頁(yè)if i == self.current_page:temp = '<a style="color:red;font-size:26px;padding: 5px" href="%s?page=%d">%d</a>' % (base_url,i,i)else:temp = '<a style="padding: 5px" href="%s?page=%d">%d</a>' % (base_url,i,i)# 把標(biāo)簽拼接然后返回給前端pager_str += tempreturn pager_strdef user_list(request):current_page = request.GET.get('page',1)page_obj = Pager(current_page)#吧方法未造成屬性(2),這樣在下面調(diào)用方法的時(shí)候就不需要加括號(hào)了result = models.UserList.objects.all()[page_obj.start:page_obj.end]all_item = models.UserList.objects.all().count()pager_str = page_obj.page_str(all_item,'/user_list/')return render(request,'user_list.html',{'result':result,'pager_str':pager_str})

前端頁(yè)面不用修改了,看效果如下:

現(xiàn)在還是有問(wèn)題的,當(dāng)你現(xiàn)在點(diǎn)擊1,2,3,4,5的時(shí)候因?yàn)榍懊鏇](méi)有頁(yè)面就會(huì)出現(xiàn)負(fù)值!

并且最后一頁(yè)頁(yè)會(huì)出現(xiàn)無(wú)窮大,但是沒(méi)有數(shù)據(jù),那怎么解決呢?

''' 如果總頁(yè)數(shù) <= 11 比如9頁(yè):那么,還有必要讓頁(yè)碼動(dòng)起來(lái)嗎?就沒(méi)必要了直接顯示總共頁(yè)數(shù)就行了!start就是1,end就是9就行了 else:如果當(dāng)前頁(yè)小宇6:start:1end:11如果當(dāng)前頁(yè)大于6:start:當(dāng)前頁(yè)-5end:當(dāng)前頁(yè)+6如果當(dāng)前頁(yè)+6 >總頁(yè)數(shù):start:總頁(yè)數(shù)-10end:總頁(yè)數(shù) '''

修改后的代碼:

#/usr/bin/env python #-*- coding:utf-8 -*-from django.shortcuts import render from django.shortcuts import HttpResponse import models # Create your views here.class Pager(object):def __init__(self,current_page):self.current_page = int(current_page)#把方法偽造成屬性(1) @propertydef start(self):return (self.current_page-1)*10@propertydef end(self):return self.current_page*10def page_str(self,all_item,base_url):all_page, div = divmod(all_item, 10)if div > 0:all_page += 1pager_str = ""# #默認(rèn)可以看到的頁(yè)碼11個(gè)# # start = self.current_page - 5# end = self.current_page + 6# # #把頁(yè)面動(dòng)態(tài)起來(lái)傳入起始和結(jié)束# for i in range(start, end):# # #判斷是否為當(dāng)前頁(yè)# if i == self.current_page:# temp = '<a style="color:red;font-size:26px;padding: 5px" href="%s?page=%d">%d</a>' % (base_url,i,i)# else:# temp = '<a style="padding: 5px" href="%s?page=%d">%d</a>' % (base_url,i,i)# # # 把標(biāo)簽拼接然后返回給前端# pager_str += tempif all_page <= 11:start = 1end = all_pageelse:if self.current_page <= 6:start = 1end = 11 + 1else:start = self.current_page - 5end = self.current_page + 6if self.current_page + 6 > all_page:start = all_page - 10end = all_page + 1#把頁(yè)面動(dòng)態(tài)起來(lái)傳入起始和結(jié)束for i in range(start, end):#判斷是否為當(dāng)前頁(yè)if i == self.current_page:temp = '<a style="color:red;font-size:26px;padding: 5px" href="%s?page=%d">%d</a>' % (base_url,i,i)else:temp = '<a style="padding: 5px" href="%s?page=%d">%d</a>' % (base_url,i,i)# 把標(biāo)簽拼接然后返回給前端pager_str += tempreturn pager_strdef user_list(request):current_page = request.GET.get('page',1)page_obj = Pager(current_page)#把方法改造成屬性(2),這樣在下面調(diào)用方法的時(shí)候就不需要加括號(hào)了result = models.UserList.objects.all()[page_obj.start:page_obj.end]all_item = models.UserList.objects.all().count()pager_str = page_obj.page_str(all_item,'/user_list/')return render(request,'user_list.html',{'result':result,'pager_str':pager_str})

這樣簡(jiǎn)單分頁(yè)就完成了,現(xiàn)在我們可以在給他增加一個(gè)“上一頁(yè)” & 下一頁(yè)

我們可以把他給為一個(gè)列表,然后每次生成的標(biāo)簽append到列表中,然后分別在列表中最前面和后面增加,上一頁(yè)和下一頁(yè)

#/usr/bin/env python #-*- coding:utf-8 -*-from django.shortcuts import render from django.shortcuts import HttpResponse import models # Create your views here.class Pager(object):def __init__(self,current_page):self.current_page = int(current_page)#把方法偽造成屬性(1) @propertydef start(self):return (self.current_page-1)*10@propertydef end(self):return self.current_page*10def page_str(self,all_item,base_url):all_page, div = divmod(all_item, 10)if div > 0:all_page += 1pager_list = []if all_page <= 11:start = 1end = all_pageelse:if self.current_page <= 6:start = 1end = 11 + 1else:start = self.current_page - 5end = self.current_page + 6if self.current_page + 6 > all_page:start = all_page - 10end = all_page + 1#把頁(yè)面動(dòng)態(tài)起來(lái)傳入起始和結(jié)束for i in range(start, end):#判斷是否為當(dāng)前頁(yè)if i == self.current_page:temp = '<a style="color:red;font-size:26px;padding: 5px" href="%s?page=%d">%d</a>' % (base_url,i,i)else:temp = '<a style="padding: 5px" href="%s?page=%d">%d</a>' % (base_url,i,i)# 把標(biāo)簽拼接然后返回給前端 pager_list.append(temp)#上一頁(yè)if self.current_page > 1:pre_page = '<a href="%s?page=%d">上一頁(yè)</a>' % (base_url, self.current_page - 1)else:# javascript:void(0) 什么都不干pre_page = '<a href="javascript:void(0);">上一頁(yè)</a>'#下一頁(yè)if self.current_page >= all_page:next_page = '<a href="javascript:void(0);">下一頁(yè)</a>'else:next_page = '<a href="%s?page=%d">下一頁(yè)</a>' % (base_url, self.current_page + 1)pager_list.insert(0, pre_page)pager_list.append(next_page)return "".join(pager_list)def user_list(request):current_page = request.GET.get('page',1)page_obj = Pager(current_page)#把方法改造成屬性(2),這樣在下面調(diào)用方法的時(shí)候就不需要加括號(hào)了result = models.UserList.objects.all()[page_obj.start:page_obj.end]all_item = models.UserList.objects.all().count()pager_str = page_obj.page_str(all_item,'/user_list/')return render(request,'user_list.html',{'result':result,'pager_str':pager_str})

最后寫成模塊,也可以吧分頁(yè)的數(shù)量動(dòng)態(tài)化!

?

前面說(shuō)過(guò)關(guān)于XSS的問(wèn)題,還有一種方式在后端告訴他是安全的即可,前端就不需要標(biāo)記了。

導(dǎo)入并使用模塊即可:

#!/usr/bin/env python #-*- coding:utf-8 -*-from django.utils.safestring import mark_safe#把拼接的HTML標(biāo)記為安全的即可return mark_safe("".join(pager_list))<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><table>{% for line in result %}<tr><td>{{ line.username }}</td><td>{{ line.age }}</td></tr>{% endfor %}</table><div>{{ pager_str }}</div></body></html>#!/usr/bin/env python #-*- coding:utf-8 -*-from django.utils.safestring import mark_safeclass Pager(object):def __init__(self,current_page):self.current_page = int(current_page)#把方法偽造成屬性(1) @propertydef start(self):return (self.current_page-1)*10@propertydef end(self):return self.current_page*10def page_str(self,all_item,base_url):all_page, div = divmod(all_item, 10)if div > 0:all_page += 1pager_list = []if all_page <= 11:start = 1end = all_pageelse:if self.current_page <= 6:start = 1end = 11 + 1else:start = self.current_page - 5end = self.current_page + 6if self.current_page + 6 > all_page:start = all_page - 10end = all_page + 1#把頁(yè)面動(dòng)態(tài)起來(lái)傳入起始和結(jié)束for i in range(start, end):#判斷是否為當(dāng)前頁(yè)if i == self.current_page:temp = '<a style="color:red;font-size:26px;padding: 5px" href="%s?page=%d">%d</a>' % (base_url,i,i)else:temp = '<a style="padding: 5px" href="%s?page=%d">%d</a>' % (base_url,i,i)# 把標(biāo)簽拼接然后返回給前端 pager_list.append(temp)#上一頁(yè)if self.current_page > 1:pre_page = '<a href="%s?page=%d">上一頁(yè)</a>' % (base_url, self.current_page - 1)else:# javascript:void(0) 什么都不干pre_page = '<a href="javascript:void(0);">上一頁(yè)</a>'#下一頁(yè)if self.current_page >= all_page:next_page = '<a href="javascript:void(0);">下一頁(yè)</a>'else:next_page = '<a href="%s?page=%d">下一頁(yè)</a>' % (base_url, self.current_page + 1)pager_list.insert(0, pre_page)pager_list.append(next_page)return mark_safe("".join(pager_list))
來(lái)源:?http://www.cnblogs.com/luotianshuai/p/5377233.html

來(lái)自為知筆記(Wiz)

轉(zhuǎn)載于:https://www.cnblogs.com/bruceg/p/5553770.html

總結(jié)

以上是生活随笔為你收集整理的自定义分页(模块化)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。