1. 程式人生 > >基於Django的python自定義分頁模組化實現

基於Django的python自定義分頁模組化實現

1、目的&環境準備

    目的:把分頁用模組方式實現,然後在需要分頁的地方直接呼叫模組。

    環境準備:建立一個Django專案,並從中生成一個App,註冊之後配置urls&Models。

    配置Urls

from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'', include("pages.urls")),
]
from django.conf.urls import url
from pages import views

urlpatterns = [
    url(r'^user_list/', views.user_list),
]

    註冊App

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

配置Models

from django.db import models


# Create your models here.
class UserList(models.Model):
    username = models.CharField(max_length=32)
    age = models.IntegerField()

2、分析&完善程式碼

    分頁功能基本上大部分網站中都是需要的,比如豆瓣話題小組的分頁,當我們檢視的時候他有很多話題討論塊,而它也不是一下子把所有的話題都返回給我們,它實現如下圖的分頁來推送博文讓我們瀏覽:

    

    而我們可以根據頁面按鈕來點選前頁和後頁或者點選我們想要檢視的頁面,然後顯示我們要檢視的話題塊和連結!而不是一下把所有內容都給我們顯示出來,這樣做的好處就是即可以節省流量又能夠改善使用者的體驗。

   那麼我們要實現這樣的功能,首先要同步表結構生成資料庫,之後建立資料(500條即可)。

    配置簡單Views建立基礎資料

from django.shortcuts import render
from django.shortcuts import HttpResponse
from pages 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')

    建立模板,配置Html顯示資料並通過Views獲取資料顯示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Pages Models</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,'page_list.html',{'result':result})

這樣,前端就可以正常顯示初始的500條資料了。但是我需要每頁顯示固定的資料量,所以我需要先獲取頁數,然後配置Urls,直接通過配置正則,用引數獲取頁面傳過來的值。

from django.conf.urls import url
from pages import views

urlpatterns = [
    url(r'^user_list/', views.user_list),
    url(r'^user_list/(?P<page>\d+)/$', views.user_list),
]
def user_list(request):
    current_page = request.GET.get('page')
    print current_page
    result = models.UserList.objects.all()[0:10]  # 每頁顯示10條資訊
    return render(request,'page_list.html',{'result':result})

    然後通過修改Views讓頁面開始和結束,即start & end 動態起來。

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)*10
    end = current_page*10  #20 30  current_page*10
    result = models.UserList.objects.all()[start:end]
    return render(request,'page_list.html',{'result':result})

    然後封裝整理Views到類和函式便於呼叫

from django.shortcuts import render
from django.shortcuts import HttpResponse
from pages import models
# Create your views here.


class Pager(object):
    def __init__(self,current_page):
        self.current_page = int(current_page)
    #把方法偽造成屬性(1)
    @property
    def start(self):
        return (self.current_page-1)*10
    @property
    def end(self):
        return self.current_page*10


def user_list(request):
    current_page = request.GET.get('page',1)
    page_obj = Pager(current_page)
    #把方法改造成屬性(2),這樣在下面呼叫方法的時候就不需要加括號了
    result = models.UserList.objects.all()[page_obj.start:page_obj.end]
    return render(request,'page_list.html',{'result':result})

    以上程式碼是通過修改瀏覽器url實現了分頁,現在我需要生成前後頁和頁數按鈕來點選實現分頁。那麼為了實現具體的效果,我們也得考慮最後頁如果資料超出怎麼辦?也就是說要通過divmod(500,10)來判斷它最後頁是否有餘數,是否是10條資料形成整頁,如果有餘數的話,我們讓其在整頁基礎加1即可以實現,即在後端生成一個大的字串然後把它返回給前端

    配置Views

from django.shortcuts import render
from django.shortcuts import HttpResponse
from pages import models
# Create your views here.


class Pager(object):
    def __init__(self,current_page):
        self.current_page = int(current_page)
    #把方法偽造成屬性(1)
    @property
    def start(self):
        return (self.current_page-1)*10
    @property
    def end(self):
        return self.current_page*10


def user_list(request):
    current_page = request.GET.get('page',1)
    page_obj = Pager(current_page)
    #吧方法未造成屬性(2),這樣在下面呼叫方法的時候就不需要加括號了
    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 +=1

    pager_str = ""
    for i in range(1,all_page+1):
        #每次迴圈生成一個標籤
        temp = '<a href="/user_list/?page=%d">%d</a>' %(i,i,)
        #把標籤拼接然後返回給前端
        pager_str += temp

    return render(request,'page_list.html',{'result':result,'pager_str':pager_str})

    配置前端頁面page_list.html

<!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>

    {{ page_str | safe }}  這樣寫是因為Django為了防止XSS攻擊產生而設定的機制,這個和我們之前學過一個CSRF跨站請求偽造的安全設定差不多。

    接下來我需要配置Views讓頁碼動態起來保持顯示固定頁數。

from django.shortcuts import render
from django.shortcuts import HttpResponse
from pages import models
# Create your views here.


class Pager(object):
    def __init__(self,current_page):
        self.current_page = int(current_page)
    #把方法偽造成屬性(1)
    @property
    def start(self):
        return (self.current_page-1)*10
    @property
    def end(self):
        return self.current_page*10

    def page_str(self,all_item,base_url):
        all_page, div = divmod(all_item, 10)

        if div > 0:
            all_page += 1

        pager_str = ""

        # #預設可以看到的頁碼11個
        #
        # start = self.current_page - 5
        # end = self.current_page + 6
        #
        # #把頁面動態起來傳入起始和結束
        # for i in range(start, end):
        #
        #     #判斷是否為當前頁
        #     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)
        #
        #     # 把標籤拼接然後返回給前端
        #     pager_str += temp

        if all_page <= 11:
            start = 1
            end = all_page
        else:
            if self.current_page <= 6:
                start = 1
                end = 11 + 1
            else:
                start = self.current_page - 5
                end = self.current_page + 6
                if self.current_page + 6 > all_page:
                    start = all_page - 10
                    end = all_page + 1

        #把頁面動態起來傳入起始和結束
        for i in range(start, end):

            #判斷是否為當前頁
            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)

            # 把標籤拼接然後返回給前端
            pager_str += temp


        return pager_str

def user_list(request):
    current_page = request.GET.get('page',1)
    page_obj = Pager(current_page)
    #把方法改造成屬性(2),這樣在下面呼叫方法的時候就不需要加括號了
    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,'page_list.html',{'result':result,'pager_str':pager_str})

    現在簡單自定義分頁就完成了,然後可以再給他增加一個“上一頁” & 下一頁

    我們也可以把他給為一個列表,然後每次生成的標籤append到列表中,然後分別在列表中最前面和後面增加,上一頁和下一頁

from django.http import HttpResponse
from django.shortcuts import render
from pages import models


class Pager(object):
    def __init__(self, current_page):
        self.current_page = int(current_page)

    # 把方法偽造成屬性(1)
    @property
    def start(self):
        return (self.current_page - 1) * 10

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


    def page_str(self, all_item, base_url):
        all_page, div = divmod(all_item, 10)

        if div > 0:
            all_page += 1

        pager_list = []

        # # 預設可以看到的頁碼11個
        #
        # start = self.current_page - 5
        # end = self.current_page + 6
        #
        # # 把頁面動態起來傳入起始和結束
        # for i in range(start, end):
        #
        #     # 判斷是否為當前頁
        #     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)
        #
        #     # 把標籤拼接然後返回給前端
        #     pager_str += temp

        if all_page <= 11:
            start = 1
            end = all_page
        else:
            if self.current_page <= 6:
                start = 1
                end = 11 + 1
            else:
                start = self.current_page - 5
                end = self.current_page + 6
                if self.current_page + 6 > all_page:
                    start = all_page - 10
                    end = all_page + 1

        # 把頁面動態起來傳入起始和結束
        for i in range(start, end):

            # 判斷是否為當前頁
            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)

            # 把標籤拼接然後返回給前端
            pager_list.append(temp)

        # 上一頁
        if self.current_page > 1:
            pre_page = '<a href="%s?page=%d">上一頁</a>' % (base_url, self.current_page - 1)
        else:
            # javascript:void(0) 什麼都不幹
            pre_page = '<a href="javascript:void(0);">上一頁</a>'
        # 下一頁
        if self.current_page >= all_page:
            next_page = '<a href="javascript:void(0);">下一頁</a>'
        else:
            next_page = '<a href="%s?page=%d">下一頁</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):
    # for i in range(500):
    #     dic = {'username': 'name_%d' % i, 'age': i}
    #     models.UserList.objects.create(**dic)
    # return HttpResponse('OK')
    current_page = request.GET.get('page', 1)
    page_obj = Pager(current_page)
    # 把方法改成屬性(2), 這樣在下面呼叫方法的時候就不需要加括號了
    # print(current_page)
    # current_page = int(current_page)
    # start = (current_page-1)*10
    # end = current_page*10
    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/')
    # all_page, div = divmod(all_item, 10)
    #
    # if div > 0:
    #     all_page += 1
    #
    # pager_str = ""
    # for i in range(1, all_page+1):
    #     # 每次迴圈生成一個標籤
    #     temp = '<a href="pages/user_list/?page=%d">%d</a>' % (i, i,)
    #     # 把標籤拼接然後返回給前端
    #     pager_str += temp
    return render(request, 'page_list.html', {'result': result, 'pager_str': pager_str})
    最後可以單獨列出來寫成模組供主專案呼叫,也可以把分頁的數量動態化,使其更好應用在專案中!

相關推薦

基於Django的python定義模組實現

1、目的&環境準備    目的:把分頁用模組方式實現,然後在需要分頁的地方直接呼叫模組。    環境準備:建立一個Django專案,並從中生成一個App,註冊之後配置urls&Models。    配置Urlsfrom django.conf.urls imp

django 1.11 定義功能的實現

在WEB中很多時候是免不了要分頁的,如果我們的資料太多了,分出來6000多頁或者更多的時候,用django自帶的分頁功能就不好看了,所以我們來自定義一下。我是參考http://www.cnblogs.com/nulige/p/6558207.html這篇文章的,不過如果照著

使用mybatis-generator新增定義外掛時提示無法例項外掛類

import org.mybatis.generator.api.CommentGenerator; import org.mybatis.generator.api.IntrospectedTable; import org.mybatis.generator.api.PluginAdapter; impo

定義1

dex forms con for type eth app public return using System; using System.Collections.Generic; using System.Linq; using System.Text; using

Python之路65-Django定義

python目錄一、XSS二、分頁1三、分頁2四、分頁3一、XSS有下面一段代碼,想將這段代碼中的字符串渲染到HTML頁面中,默認Django是不能這樣去操作的views.pydef user_list(request): page_str = """ <a href="/use

Django之定義

plugin style 定義 mage user_list .sh render 進行 blog 應用於各頁面中的分頁實現,實現的結果如下圖 1.先自定義一個有關分頁的PageInfo類 1 class PageInfo(object): 2 3

python/Djangof定義

from r+ else active count() 返回 log 多少 pan python/Djangof分頁與自定義分頁 Django分頁 1 ##============================================分頁========

laravel定義

data current clas 數字 rep 當前頁 col 自己 collect   對於laravel分頁,自帶一個paginate的方法,很好用,但是也是有局限性的。 所以自己針對於此寫了一個自己的分頁 <?php  namespace ...;use

laravel 定義 offset 和 limit 的使用

有一個 信息 代碼 自定義 快速 技術 多少 信息技術 只需要 laravel 本身有一個自帶的快速分頁方法 paginate,只需要傳入每頁顯示多少條數據就可以 了,但是如果想使用自定義從哪裏開始呢,這時候就可以使用offset 和 limit 的組合,offset 設置

Laravel 定義、可以調整、顯示數目

wid ima subst es2017 cti 選擇 admin custom -m {{-- 增加輸入框,跳轉任意頁碼和顯示任意條數 --}} <ul class="pagination pagination-sm"> <li>

Python定義程序

當前頁 start itl ati doc line mod 防止 分頁 為了防止XSS即跨站腳本攻擊,需要加上 safe # 路由 from django.conf.urls import url from django.contrib import

定義

mat 部分 pty use span 顯示 自定義分頁 封裝 sta 常規實現 data = [] for i in range(1, 302): tmp = {"id": i, "name": "alex-{}".format(i)}

python全棧系列之---定義

rip 當前 取數據 cep exce submit method next AI # coding:utf8 # __author: Administrator # date: 2018/3/7 0007 # /usr/bin/env python impo

nutz 結合QueryResult,Record 定義查詢,不構建pojo 整合

new ack long exceptio tlist call poj return .class public QueryResult getHistoryIncome(int d, int curPage) throws Exception { /**

Cookie、Session和定義

cookie值 image 分享 show base 新的 ive name pen cookie Cookie的由來 大家都知道HTTP協議是無狀態的。 無狀態的意思是每次請求都是獨立的,它的執行情況和結果與前面的請求和之後的請求都無直接關系,它不會受前面的請求響應情況直

Laravel 定義樣式

建立 img each IV com mina nta ner names 操作步驟如下: (1) 對應public/css/paging.css 文件建立分頁樣式. (2) 控制器查出分頁數據使用 paginate函數進行分頁處理.(禁止使用group by處理查詢)

Django-定義

isa 變量 range 代碼 imp lencod django mat 多少 封裝好的自定義分頁器 class Page(): def __init__(self, page_num, total_count, base_url, params, per_pa

cookie和session以及定義

cookie值 無法 解析 link try render 強制 raise 需求 cookie Cookie的由來 大家都知道HTTP協議是無狀態的。 無狀態的意思是每次請求都是獨立的,它的執行情況和結果與前面的請求和之後的請求都無直接關系,它不會受前面的請求響應情況直

DJANGO 定義組件

ret ref 前端 nav exce open 分享圖片 pro paginati 第一次在碼雲上面分享代碼片段,記錄一下: https://gitee.com/trunkslisa/codes/14gkxi3zf9e2ulbvjnqyo90 clas

Django學習手冊 - 初識定義

request shortcut ren 字符 span turn 翻頁 info char 核心: <a href=‘http://127.0.0.1:8000/index-%s‘>%s<a> 自定義分頁 1.前端處理字符   後端的字符