WEB框架-Django組件學習-分頁器學習

1.分頁器基礎學習

1.1 補充知識-批量建立

數據庫中數據批量建立,不要每建立一個就往數據庫中塞一個,會形成撞庫,形成大量I/O操做,速速較慢,應該採用一次性建立大量數據,一次性將大量數據塞入到數據庫中。css

主要用到:庫名.objects.bulk_create(數據)html

def index(request):
    book_list=[]
    for i in range(1,101):
        book = Book(title="book%s"%i,price=i*i)
        book_list.append(book)

    # 數據批量添到數據庫中
    Book.objects.bulk_create(book_list)
    return HttpResponse("ok")

展現以下前端

image

image

1.2 django自帶分頁器組件

1.2.1 django經常使用參數

#分頁器組件導入
from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger

#全局信息查詢

paginator = Paginator(book_obj,10) :分頁對象,倆個參數,第一個爲數據,第二個爲每頁展現的數量  
paginator.count:  展現分頁的數據大小
paginator.num_pages:展現總計分頁數量
paginator.page_range :相似range的數據類型

#單頁信息查詢

page = paginator.page(1)#頁面對象
page.object_list#打印當前頁面的數據量大小
page.has_next()#是否有下一頁
page.has_previous()#是否有上一頁
page.next_page_number()#當前頁的上一頁的頁碼是多少
page.previous_page_number()#當前頁的下一頁的頁碼是多少

1.2.2 其餘參數數據庫

 

1.3 分頁器的基本應用

1.3.1 分頁展現數據

def book_list(request):
  
    book_obj = Book.objects.all()
    # 分頁器對象
    paginator = Paginator(book_obj,10)
    # 獲取當前頁碼
    current_page = int(request.GET.get("page"))
    # 實例一個頁面對象
    page = paginator.page(current_page)



    return render(request,'book_list.html',locals())
#須要注意的是:在模板層記得更改循環的對象

展現以下npm

image

1.3.2 錯誤頁展現

對於超出的頁碼以及錯誤輸入默認展現第一頁django

image

展現以下,錯誤跳轉以及默認跳轉bootstrap

imageimage

1.3.3 頁面頁碼顯示

頁面頁碼展現主要是模板層代碼改變app

首先調用bootstrap,或文件或cdnide

image

頁面展現函數

image

1.3.4 上一頁,下一頁功能

上一頁,下一頁功能實現,主要用

page.has_next()#是否有下一頁
page.has_previous()#是否有上一頁
page.next_page_number()#當前頁的上一頁的頁碼是多少
page.previous_page_number()#當前頁的下一頁的頁碼是多少

展現以下

image

視圖層完整代碼

def book_list(request):

    book_obj = Book.objects.all()
    # 分頁器對象
    paginator = Paginator(book_obj,10)
    try:
        # 獲取當前頁碼,後面默認頁爲1
        current_page = int(request.GET.get("page"))
        # 實例一個頁面對象
        page = paginator.page(current_page)
    # 錯誤頁碼默認跳轉到首頁
    except EmptyPage as e:
        page = paginator.page(1)

    return render(request,'book_list.html',locals())
視圖層

模板層完整代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<h3>展現數據</h3>
<ul>
    {% for foo in page %}
        <li>{{ foo }}</li>

    {% endfor %}

</ul>
<nav aria-label="Page navigation">
  <ul class="pagination">
    {% if page.has_previous %}
        <li>
            <a href="?page={{ page.previous_page_number }}" aria-label="Previous">
            <span aria-hidden="true">上一頁</span>
          </a>
        </li>
    {% else %}
        <li class="disabled">
          <a href="#" aria-label="Previous">
            <span aria-hidden="true">上一頁</span>
          </a>
    </li>

    {% endif %}
        {% for num in paginator.page_range %}
            {% if current_page == num %}
                <li class="active"><a href="?page={{ num }}">{{ num }}</a></li>
            {% else %}
                <li><a href="?page={{ num }}">{{ num }}</a></li>
            {% endif %}

        {% endfor %}
    {% if page.has_next %}
        <li>
          <a href="?page={{ page.next_page_number }}" aria-label="Next">
            <span aria-hidden="true">下一頁</span>
          </a>
        </li>
    {% else %}
        <li class="disabled">
          <a href="#" aria-label="Next">
            <span aria-hidden="true">下一頁</span>
          </a>
        </li>
    {% endif %}

  </ul>
</nav>
</body>
</html>
模板層

1.4 分頁器的高階應用

1.4.1 動態加載頁碼

多餘多數據的時候,動態的展現頁碼,例如博客園的樣式

image

邏輯展現

主要模仿博客園這樣,在小於必定頁數,默認展現10頁,在超過必定頁數,展現左5與右5的頁碼,到最後的必定頁面,固定展現必定頁數

  • 當總頁碼小於11頁時,pageRange = paginator.page_range,展現全部頁碼便可
  • 當頁碼大於11頁時,
    • 噹噹前頁碼-5<1時,固定展現:pageRange = range(1,11)
    • 噹噹前頁碼+5>最大頁碼,展現最後11頁:pageRange=range(paginator.num_pages-10,paginator.num_pages+1)
    • 其餘則正常顯示,左5與右5頁碼:pageRange=range(current_page - 5,current_page+6)

image

2.模仿django分頁器實現本身的分頁器組件

2.1 基本展現數據

image

展現以下,又變成了最開始的樣子。。。。。

image

2.2 自定義頁碼展現

2.2.1 頁碼邏輯設置

image

處理邏輯和以前的一致,不過有部分區別就是不在 是固定的頁碼,反而是動態的獲取

2.2.2 前端頁面書寫

在一樣的函數體內書寫

image

模板層

image

最後展現

image

2.3 保留搜索條件

保留搜索條件主要是用於後面用於serch,action,分類時調用參數使用,因此須要保留搜索條件

2.3.1 補充知識點

querydict字典,默認不能編輯

image

結果報錯

image

若是想要編輯就須要導入包,進行深copy操做

image

在源碼中若是是作copy操做則能夠編輯

image

將querydict的操做轉換爲字符串操做

image

2.3.2 保留搜索條件

保留搜索條件的邏輯

image

展現以下

image

視圖層所有代碼

from django.shortcuts import render,HttpResponse

# Create your views here.
from app01.models import Book
from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger

####################################自定義組件########################################
class Pagination(object):
    def __init__(self,request,current_page,all_data,per_page_num,max_page_count=13):
        '''
        current_page :當前頁碼
        all_count:數據總大小
        per_page_num:每頁展現數量
        max_page_count:最大分頁數
        '''
        # 若是獲取非數字
        try:
            current_page = int(current_page)
        except Exception as e:
            current_page = 1

        #若是獲取小於1的數字
        if current_page<1:
            current_page = 1

        self.current_page = current_page
        self.all_count = all_data.count()
        self.per_page_num = per_page_num

        # 總頁碼
        all_pager,temp = divmod(self.all_count,self.per_page_num)
        if temp:
            all_pager +=1
        self.all_pager = all_pager

        # 最大展現頁碼以及左右最大展現頁碼
        self.max_page_count = max_page_count
        self.half_page_count = int((self.max_page_count-1)/2)
        self.request = request

        # 複製的字典
        import copy
        self.params = copy.deepcopy(self.request.GET)



    # 獲取切片數據的初始以及結束
    @property
    def start(self):
        return (self.current_page-1)*self.per_page_num

    @property
    def end(self):
        return (self.current_page)*self.per_page_num

    def page_html(self):
        #if 頁碼大於11時
        if self.all_pager >self.max_page_count:
            if self.current_page<=self.half_page_count:
                pagerange=range(1,self.max_page_count+1)
            elif self.current_page+self.half_page_count > self.all_pager:
                pagerange = range(self.all_pager-self.max_page_count+1,self.all_pager+1)
            else:
                pagerange= range(self.current_page-self.half_page_count,self.current_page+self.half_page_count+1)
        else:
            #頁碼沒有大於11
            pagerange= range(1,self.all_pager+1)

        # 構建分頁頁碼的html
        page_html_list = []
        # 首頁
        self.params["page"] = 1
        first_page = '<nav aria-label="Page navigation"><ul class="pagination"><li><a href="?%s">首頁</a></li>' % (
            self.params.urlencode(),)
        page_html_list.append(first_page)
        # 上一頁
        self.params["page"] = self.current_page - 1
        if self.current_page <= 1:
            prev_page = '<li class="disabled"><a href="#">上一頁</a></li>'
        else:
            prev_page = '<li><a href="?%s">上一頁</a></li>' % (self.params.urlencode(),)

        page_html_list.append(prev_page)
        # self.params: ["page":9,"a":1,"b":2]
        # 正常展現頁碼
        for i in pagerange:
            self.params["page"] = i
            if i == self.current_page:
                temp = '<li class="active"><a href="?%s">%s</a></li>' % (self.params.urlencode(), i,)
            else:
                temp = '<li><a href="?%s">%s</a></li>' % (self.params.urlencode(), i,)
            page_html_list.append(temp)
        # 下一頁
        self.params["page"] = self.current_page + 1
        if self.current_page >= self.all_pager:
            next_page = '<li class="disabled"><a href="#">下一頁</a></li>'
        else:
            next_page = '<li><a href="?%s">下一頁</a></li>' % (self.params.urlencode(),)
        page_html_list.append(next_page)
        # 尾頁
        self.params["page"] = self.all_pager
        last_page = '<li><a href="?%s">尾頁</a></li> </ul></nav>' % (self.params.urlencode())
        page_html_list.append(last_page)

        return ''.join(page_html_list)



def book_list2(request):

    book_list= Book.objects.all()
    current_page = int(request.GET.get("page", 1))
    pagination = Pagination(request,current_page,book_list,per_page_num=10)

    book_list=book_list[pagination.start:pagination.end]

    return render(request,'book_list2.html',locals())
視圖層代碼

模板層所有代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

</head>
<body>
    <ul>
        {% for book in book_list  %}
        <li>{{ book }}</li>
        {% endfor %}

    </ul>
{{ pagination.page_html|safe }}


</body>
</html>
模板層代碼

a

相關文章
相關標籤/搜索