1. 程式人生 > >django中orm分頁功能(內置分頁)

django中orm分頁功能(內置分頁)

com 模塊 ren block views ext 如何解決 name view

分批獲取數據的方法

數據庫方法

models.Uinfo.objects.all()[10:20]

django自帶的方法

創建一個新的url

urlpatterns = [
    url(r‘^index.html/‘, views.index),
]

創建index函數

def index(request):
    """
    分頁功能
    :param request:
    :return:
    """
    user_list = models.Uinfo.objects.all()#獲取到數據
    return render(request,‘index.html‘,{‘user_list‘:user_list})#返回到index頁面上顯示

創建index.html頁面

在templates目錄下面創建index頁面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用戶列表</title>
</head>
<body>
    <h1>用戶列表</h1>
    <ul>
        {% for user in user_list %}
            <li>{{ user.name }}</li>
        {% endfor %}

    </ul>
</body>
</html>

瀏覽器訪問

通過瀏覽器訪問可以看到結果都顯示到了index的頁面上
技術分享圖片

存在的問題

通過瀏覽器訪問,發現所有的用戶都顯示到了頁面上,但是有一個問題,如果數據庫中有上千,百萬個數據,這一個頁面要全部顯示出來是很卡,也很不好。那麽如何解決這些問題那。

給數據庫添加數據

def index(request):
        #下面的for循環是給數據庫中添加200條數據
    for i in range(200):
        name = "root" + str(i)
        models.Uinfo.objects.create(name=name,age=18,ut_id=1)
    user_list = models.Uinfo.objects.all()
    return render(request,‘index.html‘,{‘user_list‘:user_list})

在index函數裏面寫入上面代碼後,重新瀏覽器訪問index.html,讓數據庫生成上面的數據。

使用django的paginator分頁

def index(request):
    """
    分頁功能
    :param request:
    :return:
    """
    # for i in range(200):
    #     name = "root" + str(i)
    #     models.Uinfo.objects.create(name=name,age=18,ut_id=1)
    from django.core.paginator import Paginator,Page#導入模塊
    current_pagnum = request.GET.get(‘page‘)
    user_list = models.Uinfo.objects.all()
    paginator = Paginator(user_list,10)
        #創建一個對象paginator,又有這是一個對象,所以可以通過點“.”來調用一些功能
    # per_page: 每頁顯示條目數量
    # count:    數據總個數
    # num_pages:總頁數
    # page_range:總頁數的索引範圍,如: (1,10),(1,200)
    # page:     page對象
    posts = paginator.page(number=current_pagnum)#這個num就是現實當前第幾頁
    # has_next              是否有下一頁
    # next_page_number      下一頁頁碼
    # has_previous          是否有上一頁
    # previous_page_number  上一頁頁碼
    # object_list           分頁之後的數據列表
    # number                當前頁
    # paginator             paginator對象
    return render(request,‘index.html‘,{‘posts‘:posts}) 

index頁面的修改

    <ul>
        {% for user in posts.object_list %}#使用的上上post對象object_list功能
            <li>{{ user.name }}</li>
        {% endfor %}

完成上面的代碼,瀏覽器訪問http://127.0.0.1:8000/index.html/?page=1傳入參數page,就能訪問到10條數據
技術分享圖片

上一頁下一頁功能

下一頁功能

修改index.html頁面的代碼

<body>
    <h1>用戶列表</h1>
    <ul>
        {% for user in posts.object_list %}
            <li>{{ user.name }}</li>
        {% endfor %}
    </ul>
    <div>
        {% if posts.has_next %}
            <a href="/index.html/?page={{ posts.next_page_number }}">下一頁</a>

        {% endif %}
    </div>
</body>

上一頁功能

<body>
    <h1>用戶列表</h1>
    <ul>
        {% for user in posts.object_list %}
            <li>{{ user.name }}</li>
        {% endfor %}
    </ul>
    <div>
        {% if posts.has_previous %}
            <a href="/index.html/?page={{ posts.previous_page_number }}">上一頁</a>
        {% endif %}
        {% if posts.has_next %}
            <a href="/index.html/?page={{ posts.next_page_number }}">下一頁</a>
        {% endif %}
    </div>
</body>

判斷url輸入page不是整數

當訪問連接是:http://127.0.0.1:8000/index.html/?page=dfa page傳遞的一個參數是一個非數字的時候,我們這個時候可以使用try來抓補異常來處理

 from django.core.paginator import Paginator,Page,PageNotAnInteger#首先把這個異常導入進來
     try:
        posts = paginator.page(number=current_pagnum)#這個num就是現實當前第幾頁
    except PageNotAnInteger:
        posts = paginator.page(number=1)

如果page傳遞過來的是一個負數eg:-1,雖然不是字符串,但是也要報錯,這個時候也是可以抓捕異常的
技術分享圖片

頁碼的功能

        {% for num in posts.paginator.page_range %}#在posts對象裏面有一個paginator對象,這個對象的下面有一個頁碼範圍page_range,通過連續的導入使用
            <a href="/index.html/?page={{ num }}">{{ num }}</a>
        {% endfor %}

技術分享圖片
但是django不適合用來加頁碼,因為他會全部都顯示出來

自己定義分頁

創建路由和函數

 url(r‘^custom.html/‘, views.custom),
def custom(request):
    #獲取當前頁
    current_page = request.GET.get(‘page‘)
    current_page = int(current_page)
    #每頁顯示10條
    per_page = 10
    #1,0-10
    #2,10-20
    #3,20-30
    start_page = (current_page -1) * per_page
    end_page = current_page * per_page
    user_list = models.Uinfo.objects.all()[start_page:end_page]
    return render(request,‘custom.html‘,{‘user_list‘:user_list})

創建頁面

<body>
    <ul>
        {% for user in user_list %}
            <li>{{ user.name }}</li>

        {% endfor %}

    </ul>
</body>

結果

通過http://127.0.0.1:8000/custom.html/?page=2 輸入不同的數字顯示頁碼,後臺通過轉換

代碼優化

初始化的東西,創建一個類,全部放在類中操作

class PageInfo(object):
    def __init__(self,current_page,per_page):
        try:
            self.current_page = int(current_page)
        except Exception as e:
            self.current_page = 1
        self.per_page = per_page

    def start(self):
        return (self.current_page -1)*self.per_page

    def end(self):
        return self.current_page * self.per_page
def custom(request):
    page_info = PageInfo(request.GET.get(‘page‘),10)
    user_list = models.Uinfo.objects.all()[page_info.start():page_info.end()]
    return render(request,‘custom.html‘,{‘user_list‘:user_list})

添加自定義頁碼功能

類中的代碼

技術分享圖片

函數中的代碼

技術分享圖片

頁面中的代碼

技術分享圖片

瀏覽結果

技術分享圖片

對上面的瀏覽結果優化下

技術分享圖片

添加選中當前頁的背景色

技術分享圖片
技術分享圖片

固定顯示頁數

技術分享圖片
技術分享圖片
但是這個是有bug的,如果前面沒有頁數了,會顯示負數

優化顯示的頁數

   def pager(self):
        page_list =[]
        half_page = int((self.show_page -1)/2)

        if self.all_pages < self.show_page:
            start_showpage = 1
            stop_showpage = self.all_pages + 1
        else:
            if self.current_page <= half_page:
                start_showpage = 1
                stop_showpage = self.show_page +1
            else:
                if self.current_page + half_page > self.all_pages:
                    start_showpage = self.all_pages - self.show_page + 1
                    stop_showpage = self.all_pages + 1
                else:
                    start_showpage = self.current_page - half_page
                    stop_showpage = self.current_page + half_page + 1
        if self.current_page <=1:
            prev_page = "<a style=‘display:inline-block;padding:5px;marign:5px;‘ href=‘#‘>上一頁</a>"
        else:
            prev_page = "<a style=‘display:inline-block;padding:5px;marign:5px;‘ href=‘/custom.html/?page=%s‘>上一頁</a>" %(self.current_page -1)
        page_list.append(prev_page)
        # for num in range(1,self.all_pages+1):
        for num in range(start_showpage,stop_showpage):
            if num == self.current_page:
                temp = "<a style=‘display:inline-block;padding:5px;marign:5px;background-color:red;‘ href=‘/custom.html/?page=%s‘>%s</a>" % (
                num, num,)
            else:
                temp="<a style=‘display:inline-block;padding:5px;marign:5px;‘ href=‘/custom.html/?page=%s‘>%s</a>" %(num,num,)
            page_list.append(temp)

        if self.current_page >self.all_pages:
            next_page = "<a style=‘display:inline-block;padding:5px;marign:5px;‘ href=‘#‘>下一頁</a>"
        else:
            next_page = "<a style=‘display:inline-block;padding:5px;marign:5px;‘ href=‘/custom.html/?page=%s‘>下一頁</a>" %(self.current_page +1)
        page_list.append(next_page)

        return "".join(page_list)

結果顯示

技術分享圖片

優化url自動

通過占位符,來動態的生成url。首先給一個參數位置
技術分享圖片
把a標簽中的href修改成占位符
技術分享圖片
傳遞參數的時候傳入url
技術分享圖片

通過bootstrip來美化分頁

首先導入bootstrip到項目中

<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">

https://v3.bootcss.com/components/#pagination

可以看到文檔介紹的都是ul,li格式的分頁,而我們開始使用的是a標簽,所以下面我們要把我們的a標簽改成li形式的
技術分享圖片
全部改成li標簽後,我們在頁面上引用

<body>
    <ul>
        {% for user in user_list %}
            <li>{{ user.name }}</li>
        {% endfor %}
    </ul>

    <nav aria-label="Page navigation">
  <ul class="pagination">
     {{ page_info.pager|safe }}#這裏把案例的li刪除更換成我們的代碼即可
  </ul>
</nav>
</body>

添加上背景色

技術分享圖片

django中orm分頁功能(內置分頁)