Django博客开发拓展 | 通过Ajax加载下一页


2020年4月2日 22:40 阅读 888 评论 0 Django

在写这个博客时我看了很多人的博客,对于首页的文章显示基本都是大同小异:在最后一篇博文的下面放置分页按钮,点击哪一页就去哪一页。 但是我觉得这样太大众化,直到我看到了崔大的博客,是监听页面滑动来自动加载下一页的,我觉得这样还不错,于是就仿照着做了一个,但是写完我发现下拉滑动监听虽然很智能但是也有缺点:

  • 下拉有延迟,不能完全做到随拉随加载,可能是我技术不够吧,吐

  • 严重影响用户体验,我就经常被一些无限下拉加载的网页搞得很烦,有时候你就是想看看底部的东西。。。

所以我费了很大功夫写出来之后,第二天就舍弃了,我采用了一种新办法,在文章列表的底部加了一个加载下一页的按钮,让用户自行选择加载与否,我觉得这样才是比较友好的方式

后端使用Django自带的分页器进行分页:

from django.core.paginator import Paginator 
from django.views import generic 
class IndexView(generic.ListView):# ListView下次再说 
    model = Article 
    template_name = 'index.html' 
    context_object_name = 'posts' 
    paginate_by = 5 #一页五篇博文 

前端很简单,放一个button以及点击button之后加载的动画,bootstrap4就有现成的,我搬来改改就用了,大致如下:

<!-- page_obj:django.core.paginator.Page的实例,如果未分页,则此上下文变量将为None--> 
<!-- 这里的作用是如果没分页就不显示下一页按钮,因为没有下一页。。--> 
{% if page_obj %} 
<button type="button" class="btn btn-info btn-lg btn-block mt-3" id="load_btn">下一页</button> 
<!-- 下方动画默认隐藏 --> 
<div class="text-center d-none p-2 m-2" id="loading"> 
    <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> 
    数据载入中... 
</div> 
{% endif %} 

获取下一页的后端如下:

page = request.GET.get('page') # 获取页码 
posts = Article.objects.all().order_by('-created_time') # 按时间排序查询所有文章 
"""next_page : True 关闭前端下一页按钮 False 显示下一页按钮""" 
try: # 做异常处理,以免出现页码不存在等等情况 
    posts = paginator.page(page) 
except EmptyPage:# 没有这一页时返回空数据,隐藏按钮 
    return JsonResponse({'code': -1, 'data': '', 'next_page': False}) 
except:# 其他异常时返回空数据,隐藏按钮 
    return JsonResponse({'code': -1, 'data': '', 'next_page': False}) 
else:# 若没有错误加载模板填充数据返还给前端显示 
    html = loader.render_to_string('blog_list.html', {'posts': posts}) 
    # 若前端传递来的页码与分页器的页码相同则此页为最后一页,让前端关闭加载按钮 
    if int(page) == paginator.num_pages: 
        return JsonResponse({'code': 0, 'data': html, 'next_page': False}) 
    return JsonResponse({'code': 0, 'data': html, 'next_page': True}) 

然后通过ajax来实现无刷新加载下一页

var page = 2;初始化页码为2 
$("#load_btn").click(function () { // 点击见下一页按钮时执行以下方法 
    $("#load_btn").hide(); //按钮隐藏 
    $("#loading").removeClass('d-none'); // 加载动画显示 
    $.get({ 
        url: '/article_list', 
        data: { 
            page: page 
        }, 
        success: function (res) { 
            if (res.code < 0) { //若后端异常 
                $("#loading").addClass('d-none');// 隐藏加载动画 
            } else { // 若成功返回数据 
                setTimeout(function () { //延时500ms填充数据 
                    $("#blog_list").append(res.data); 
                    $("#loading").addClass('d-none');// 填充完数据后隐藏加载动画 
                    if (!res.next_page) { //判断是否有下一页来隐藏/显示下一页按钮 
                        $("#load_btn").hide(); 
                    } else { 
                        $("#load_btn").show(); 
                    } 
                }, 500); 
                page += 1 // 页码+1 
            } 
        }, error: function () { 
            $("#loading").addClass('d-none') //若请求出错则隐藏加载动画 
        } 
    }); 
}); 

这样一个完整的ajax请求下一页就做出来了,我将它运用在了首页和分类/标签/搜索查询上,可以在博客里体验

最后修改于2020年4月2日 22:40
©允许规范转载

版权声明:如无特殊说明,文章均为本站原创,转载请注明出处

本文链接:https://www.yyqblog.com/article/16.html

微信
支付宝
提交数据中...