Django-----分頁

一、目的

    因爲往往數據庫中的數據在前端頁面展示出來一頁肯定是不夠的,而一個網頁的容量就那麼大,所以肯定要分頁顯示。


二、實施

    其實仔細想想,如果數據量小的話,直接在後臺的views處理函數中分批的去獲取數據就可以,比如:

models.UserInfo.objects.all()[0:10]  #UserInfo代表數據表,[0:10]表示獲取第一個到第十個數據
models.UserInfo.objects.all()[0:10]   #同上


django中自帶分頁功能,需要導入Paginator模塊,如下:

from django.core.paginator import Paginator,Page

cur_page = request.GET.get('page')   #獲取用戶請求中的當前頁碼,示例使用url--GET傳值
#http://127.0.0.1:8000/index.html/?page=1
user_list = models.UserInfo.objects.all()
paginator = Paginator(user_list,10)
'''
這個paginator對象中帶有如下屬性:
#per_page:每頁顯示條目數量
#count:數據總個數
#num_pages:總頁數
#page_range:總頁數的索引範圍,如:(1,10),(1,200)
#page:page對象
'''

posts = paginator.page(cur_page)  #如果當前頁不是數字或者頁碼是負數的話在此加try...except
'''
# has_next              是否有下一頁
# next_page_number      下一頁頁碼
# has_previous          是否有上一頁
# previous_page_number  上一頁頁碼
# object_list           分頁之後的數據列表
# number                當前頁
# paginator             paginator對象
'''

return render(request,'index.html',{'posts':posts}  #將posts傳到模板進行渲染返回頁面
#模板代碼如下:
<ul>
        {% for row in posts.object_list %}  #通過posts的object_list屬性獲取所有的數據行
            <li>{{ row.name }}</li>
        {% endfor %}
    </ul>
    <div>
        {% if posts.has_previous %}   #判斷如果posts對象有上一頁則渲染上一頁
            <a href="/index.html?page={{ posts.previous_page_number }}">上一頁</a>
        {% endif %}
         {% for num in posts.paginator.page_range %} 
             <a href="/index.html/?page={{ num }}">{{  num  }}</a>
             {% endfor %}
        {% if posts.has_next %}    #判斷下一頁
            <a href="/index.html?page={{ posts.next_page_number }}">下一頁</a>
        {% endif %}
    </div>

注:上述django自帶的分頁功能會將所有頁碼全部顯示,是有一定的侷限性的,只適合有上一頁下一頁的網頁,如果需要顯示限定數目的頁碼的話就需要自己定製了,而且此種方法也只能在django框架中用,換作其他框架也不行。


三、自定義分頁功能

#分頁模塊,封裝成類,以後直接使用即可
class PageInfo(object):

    def __init__(self,current_page,all_count,per_page,base_url,show_page=11):
        """

        :param current_page:當前頁
        :param all_count: 數據庫總行數
        :param per_page: 每頁顯示函數
        :base_url:url前綴
        :show_page:
        :return:
        """
        try:
            self.current_page = int(current_page) #如果頁碼不合理跳轉到第一頁
        except Exception as e:
            self.current_page = 1
        self.per_page = per_page

        a,b = divmod(all_count,per_page)  #通過數據庫數據總條數和每頁顯示的數據條數獲取
        if b:                              #總頁數(餘數不爲0總頁數多顯示1頁)
            a = a +1
        self.all_pager = a
        self.show_page = show_page
        self.base_url = base_url
    def start(self):                    #數據起始位置
        return (self.current_page-1) * self.per_page

    def end(self):                       #數據結束位置
        return self.current_page * self.per_page 


    def pager(self):
        page_list = []   #用於在模板中渲染所要顯示的頁碼

        half = int((self.show_page-1)/2)   

        # 如果數據總頁數 < 11 需要顯示全部頁碼
        if self.all_pager < self.show_page:
            begin = 1
            stop = self.all_pager + 1
        # 如果數據總頁數 > 11 
        else:
            # 如果當前頁 <=5,永遠顯示1,11
            if self.current_page <= half:
                begin = 1
                stop = self.show_page + 1
            else:
                if self.current_page + half > self.all_pager:
                    begin = self.all_pager - self.show_page + 1
                    stop = self.all_pager + 1
                else:
                    begin = self.current_page - half
                    stop = self.current_page + half + 1

        if self.current_page <= 1:
            prev = "<li><a href='#'>上一頁</a></li>"   #當前頁爲1則上一頁點擊不跳轉
        else:
            prev = "<li><a href='%s?page=%s'>上一頁</a></li>" %(self.base_url,self.current_page-1,)
        page_list.append(prev)  #先將上一頁標籤添加到需要渲染的頁碼列表

        for i in range(begin,stop):
            if i == self.current_page:  #引入bootstrap,給選中頁碼加樣式
                temp = "<li class='active'><a  href='%s?page=%s'>%s</a></li>" %(self.base_url,i,i,)
            else:
                temp = "<li><a href='%s?page=%s'>%s</a></li>" %(self.base_url,i,i,)
            page_list.append(temp)

        if self.current_page >= self.all_pager:   #將下一頁添加在頁碼最後
            nex = "<li><a href='#'>下一頁</a></li>"
        else:
            nex = "<li><a href='%s?page=%s'>下一頁</a></li>" %(self.base_url,self.current_page+1,)
        page_list.append(nex)


        return ''.join(page_list)  #將頁碼標籤列表拼接成字符串返回

分頁時需要做的三件事:

    1、創建處理分頁數據的類

    2、根據分頁數據獲取數據

    3、輸出分頁HTML並且適當的加一些樣式

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章