Django ajax異步請求分頁的實現


Django中有一個自帶的Paginator分頁器,用起來很方便的在原生的模板中進行調用函數分頁;

可是每次點擊換頁都會重新載入頁面,原來是原生分頁器依靠的是A標簽的GET請求實現的,這就要用ajax異步請求來解決這個尷尬的情況,(有時同一頁面會有多個不同的分類需要添加分頁器的場景等),但是ajax回調時接收的是json,而json不能給模板傳入對象,該怎么分頁呢?

1、就將分頁需要用到的數據從對象中提前取出來,放在字典里面

2、前台調用時候不再從對象中取,而是字典中取,完成分頁樣式; 

我把一個我自己寫的代碼附上,一看就明白了。(沒做修改,HTML代碼部分凌亂一些。。)

HTML部分:

 {#分頁開始#}
                <div aria-label="Page navigation">
                    <ul class="pagination">
                        {% if page_previous %}
                            <li value="{{ page_previous }}"><a href="javascript:void(0);" aria-label="Previous"><span
                                    aria-hidden="true">上一頁</span></a></li>
                        {% else %}
                            <li value="{{ page_previous }}" class="disabled"><a href="javascript:void(0);" aria-label="Previous"><span
                                    aria-hidden="true">上一頁</span></a></li>
                        {% endif %}
                        {% for page_nums in current_range %}
                            {% if current_page_num == page_nums %}
                                <li value="{{ page_nums }}" class="active"><a href="javascript:void(0);">{{ page_nums }}</a></li>
                            {% else %}
                                <li value="{{ page_nums }}"><a href="javascript:void(0);">{{ page_nums }}</a></li>
                            {% endif %}
                        {% endfor %}
                        {% if page_next %}
                            <li value="{{ page_next }}"><a href="javascript:void(0);" aria-label="Next"><span
                                    aria-hidden="true">下一頁</span></a></li>
                        {% else %}
                            <li value="{{ page_next }}" class="disabled"><a href="javascript:void(0);" aria-label="Next"><span
                                    aria-hidden="true">下一頁</span></a>
                            </li>
                        {% endif %}
                    </ul>
                </div>

代碼部分(自定義函數,也可直接在views.py中):

from django.core.paginator import Paginator, EmptyPage


def pages(request, format_title_list, row_num):
    paginator = Paginator(format_title_list, row_num)  # 使用Paginator方法得到paginator對象

    ###### paginator對象的方法 #########
    # print(paginator.count)         #顯示所有數據條數
    # print(paginator.page_range)    #分頁器的頁數范圍
    # print(paginator.num_pages)     #分液器總頁數

    current_page_num = int(request.GET.get('page', 1))  # 獲得請求的頁數,默認值為1,當GET沒有值時顯示第一頁的內容。
    # 以下是頁面顯示效果:,當頁數大於11頁數時,將顯示當前頁的前5頁和后5頁的頁碼,如果選擇的頁碼小於5時,顯示的頁碼為1至11頁,如果頁碼加5大於最大頁碼數時,顯示最后11頁的頁碼。    如果總頁數小於11頁時就正常顯示頁碼。
    if paginator.num_pages > 11:
        if current_page_num - 5 < 1:  # 當前頁-5如果小於1的話,說明頁碼已經是小於5的,那么頁碼范圍就顯示前11頁數。
            # 這里也可以寫成 if current_page_num < 6 。這樣顯得更容易理解。
            current_range = range(1, 11)
        elif current_page_num + 5 > paginator.num_pages:  # 當前頁碼+5大於最大頁碼時,說明已經到達最后的5頁了。那么頁碼范圍就顯示后11頁數。
            # 這里也可以寫成 elif current_page_num > paginator.num_pages-5 。容易理解。
            current_range = range(paginator.num_pages - 10, paginator.num_pages + 1)
        else:
            current_range = range(current_page_num - 5, current_page_num + 6)  # 顯示當前頁的前五和后五頁碼數。
    else:
        current_range = paginator.page_range  # 否則正常顯示頁碼數。
    try:
        current_page = paginator.page(current_page_num)  # 當頁碼超出范圍時,會拋出異常。
        # page1 = paginator.page(1)
        # print(page1.object_list)
        # for i in page1:
        #     print(i)
    except EmptyPage as e:  # 異常的解決方案為當前頁碼內容顯示為第一頁。
        current_page = paginator.page(1)

    page_previous = current_page.previous_page_number() if current_page.has_previous() else 0  #得到上一頁
    page_next = current_page.next_page_number() if current_page.has_next() else 0  #得到下一頁
    current_range = list(current_range)  #當前頁碼范圍
    current_page = list(current_page)  #當前頁內容(文章標題)
    return {'current_range': current_range, 'current_page': current_page, 'current_page_num': current_page_num,
            'page_previous': page_previous, 'page_next': page_next}

views.py中

def workingpaper(request):
    #上面代碼全部省略
        article_list = Article.objects.all().order_by('-pk')  #獲得所有文件queryset對象列表
        article_format_title = formattitle.format_title(article_list, 43)  #自定義方法,用來格式化標題在渲染頁面時的長度統一。(在我的博客里有這部分源碼)
        ret_page = mypaginator.pages(request, article_format_title, 10)   #自定義方法,分頁器方法的調用。
    return render(request, 'workingpaper.html', {'current_range': ret_page['current_range'],
                                                 'current_page': ret_page['current_page'],
                                                 'current_page_num': ret_page['current_page_num'],
                                                 'page_previous': ret_page['page_previous'],
                                                 'page_next': ret_page['page_next']})

jquery部分

function paginator(data) {
    $('.pagination li').remove();

    if (data['page_previous']) {
        $('.pagination').append("<li value='" + data['page_previous'] + "'><a href='javascript:void(0);' aria-label='Previous'><span aria-hidden='true'>上一頁</span></a></li>")
    } else {
        $('.pagination').append("<li value='" + data['page_previous'] + "' class='disabled'><a href='javascript:void(0);' aria-label='Previous'><span aria-hidden='true'>上一頁</span></a></li>")
    }
    for (var k in  data['current_range']) {
        if (data['current_page_num'] == data['current_range'][k]) {
            $('.pagination').append('<li value="' + data['current_range'][k] + '" class="active"><a href="javascript:void(0);">' + data["current_range"][k] + '</a></li>')
        } else {
            $('.pagination').append('<li value="' + data['current_range'][k] + '"><a href="javascript:void(0);">' + data["current_range"][k] + '</a></li>')
        }
    }
    if (data['page_next']) {
        $('.pagination').append("<li value='" + data['page_next'] + "'><a href='javascript:void(0);' aria-label='Previous'><span aria-hidden='true'>下一頁</span></a></li>")
    } else {
        $('.pagination').append("<li value='" + data['page_next'] + "' class='disabled'><a href='javascript:void(0);' aria-label='Previous'><span aria-hidden='true'>下一頁</span></a></li>")
    }
}

function set_li(data) {
    $('.ul-list li').remove();
    for (var i = 0; i < data['current_page'].length; i++) {
        $('.ul-list').append("<li value=" + data['current_page'][i].nid + "><a herf='javascript:void(0);'><span class='glyphicon glyphicon-menu-right'></span>" +
            data['current_page'][i].title + "</a></li>");
    }
}

var class_mark = 'page'; //用於做翻頁器的類別標識
var class_field = '';  //用於傳遞類別中的具體篩選條件
$('.pagination').on('click', 'li', function () {
    console.log(class_mark);
    $.ajax({
        url: '',
        type: 'get',
        data: {
            page: $(this).val(),
            class_name: class_mark,
            id: class_field,
            retdate: class_field,
        },
        success: function (data) {
            set_li(data);
            paginator(data)
        }
    })
});

$('.ul-list').on('click', 'a', function () {
    var num = $('.ul-list li').val();
    location.href = "/text/" + num
});

$('.showalldptlist').click(function () {
    class_mark = 'page';
    class_field = $(this).val();
    $.ajax({
        url: "",
        type: 'get',
        data: {
            page: $(this).val(),
            class_name: 'page',
        },
        success: function (data) {
            set_li(data);
            paginator(data);
        }
    })
});

效果圖:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM