• Django基础五之Ajax


    Django基础五之Ajax

    1. Ajax介绍

    2. Ajax前后端传值

    image

    在输入框一和输入框二中分别输入一个数字,然后点提交在第三个输入框中显示结果.

    HTML代码:

    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <input type="text" id="d1" >+
                <input type="text" id="d2">=
                <input type="text" id="d3">
                <button id="d4" class="btn">提交</button>
            </div>
        </div>
    </div>
    </body>
    

    2.1 方法一HttpResponse直接返回

    html页面代码:

    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <input type="text" id="d1" >+
                <input type="text" id="d2">=
                <input type="text" id="d3">
                <button id="d4" class="btn btn-warning">提交</button>
            </div>
        </div>
    </div>
    
    <script>
        $("#d4").click(function (){
            var num1 = $("#d1").val();
            var num2 = $("#d2").val();
            console.log(num1, num2);
    
            //拿到参数后使用Ajax向后提交
            $.ajax({
                url:"/index/",  // 请求的地址
                type:"post",    // 请求的方式, 使用method()也可以
                data:{num1:num1, num2:num2},   //指定要提交给后端的数据
                success: function (res){ // 返回成功走sucess,接收后端返回的结果
                    // 后端返回的数据都放在res里面
                    console.log(res)
                    $('#d3').val(res)
                   // .val()里面什么都不写为取值, 如果里面写数据为设置值
                }
            });
    
        })
    </script>
    </body>
    

    views.py代码

    from django.shortcuts import render,HttpResponse
    
    def index(request):
        if request.method == 'POST':  #     if request.is_ajax(): 判断是不是ajax请求
            n1 = request.POST.get('num1')
            n2 = request.POST.get('num2')
            n3 = int(n1) + int(n2)
            return HttpResponse(n3)
        return render(request, 'index.html')
    

    2.2 方法二使用Json格式返回

    上面例子返回的是个数字,如果返回的是多个值,或者是不同的类型,那么就要用json格式传输

    2.2.1 HttpResponse 返回json类型

    from django.shortcuts import render,HttpResponse
    # Create your views here.
    
    def index(request):
        #if request.method == 'POST':
        if request.is_ajax():
            n1 = request.POST.get('num1')
            n2 = request.POST.get('num2')
            n3 = int(n1) + int(n2)
            res_dict = {'username':'Hans', 'n3':n3}
            import json
            # 序列化成json类型的字符串
            res_dict = json.dumps(res_dict)
            return HttpResponse(res_dict)
        return render(request, 'index.html')
    

    前端处理Json

    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <input type="text" id="d1" >+
                <input type="text" id="d2">=
                <input type="text" id="d3">
                <button id="d4" class="btn btn-warning">提交</button>
            </div>
        </div>
    </div>
    
    <script>
        $("#d4").click(function (){
            var num1 = $("#d1").val();
            var num2 = $("#d2").val();
            console.log(num1, num2);
    
            //拿到参数后使用Ajax向后提交
            $.ajax({
                url:"/index/",  // 请求的地址
                type:"post",    // 请求的方式,使用method()也可以
                data:{num1:num1, num2:num2},   //指定要提交给后端的数据
                success: function (res){ // 接收后端返回的结果
                    // 后端返回的数据都放在res里面
    				// 后端传过来的是json格式的string,所以要先反序列化
                    res_json = JSON.parse(res)
                    // 取值                    
                    console.log(res_json.n3)
                    $('#d3').val(res_json.n3)
                }
            });
    
        })
    </script>
    </body>
    

    2.2.2 JsonResponse返回

    views.py

    from django.shortcuts import render,HttpResponse
    from django.http import  JsonResponse
    # Create your views here.
    
    def index(request):
        if request.is_ajax():
            n1 = request.POST.get('num1')
            n2 = request.POST.get('num2')
            n3 = int(n1) + int(n2)
            res_dict = {'username':'Hans', 'n3':n3}
            return JsonResponse(res_dict)
        return render(request, 'index.html')
    

    前端处理

    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <input type="text" id="d1" >+
                <input type="text" id="d2">=
                <input type="text" id="d3">
                <button id="d4" class="btn btn-warning">提交</button>
            </div>
        </div>
    </div>
    
    <script>
        $("#d4").click(function (){
            var num1 = $("#d1").val();
            var num2 = $("#d2").val();
            console.log(num1, num2);
    
            //拿到参数后使用Ajax向后提交
            $.ajax({
                url:"/index/",  // 请求的地址
                type:"post",    // 请求的方式,使用method()也可以
                data:{num1:num1, num2:num2},   //指定要提交给后端的数据
                success: function (res){ // 接收后端返回的结果
                    // 后端返回的数据都放在res里面
                    console.log(res)
                    console.log(typeof(res))
    				// 后端使用JsonResponse直接返回一个对象,所以不用使用json反序列化(Django1.11依然要反序列化),直接使用
                    $('#d3').val(res.n3)
                }
            });
    
        })
    </script>
    </body>
    
    

    使用JsonResponse返回的时候,它返回kwargs.setdefault('content_type', 'application/json') 直接返回的为application/json,ajax可以直接转成对象类型.

    2.2 方法三使用HttpResponse 返回,但前端不做反序列化

    views.py

    from django.shortcuts import render,HttpResponse
    # Create your views here.
    
    def index(request):
        #if request.method == 'POST':
        if request.is_ajax():
            n1 = request.POST.get('num1')
            n2 = request.POST.get('num2')
            n3 = int(n1) + int(n2)
            res_dict = {'username':'Hans', 'n3':n3}
            print(res_dict)
            import json
            res_dict = json.dumps(res_dict)
            return HttpResponse(res_dict)
        return render(request, 'index.html')
    

    前端处理

    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <input type="text" id="d1" >+
                <input type="text" id="d2">=
                <input type="text" id="d3">
                <button id="d4" class="btn btn-warning">提交</button>
            </div>
        </div>
    </div>
    
    <script>
        $("#d4").click(function (){
            var num1 = $("#d1").val();
            var num2 = $("#d2").val();
            console.log(num1, num2);
    
            //拿到参数后使用Ajax向后提交
            $.ajax({
                url:"/index/",  // 请求的地址
                type:"post",    // 请求的方式,使用method()也可以
                data:{num1:num1, num2:num2},   //指定要提交给后端的数据
                dataType:"json",   // 指定后端返回的数据格式
                success: function (res){ // 接收后端返回的结果
                    // 后端返回的数据都放在res里面
                    console.log(res)
                    console.log(typeof(res))
    				//指定了格式为json,则直接使用即可
                    $('#d3').val(res.n3)
                }
            });
    
        })
    </script>
    </body>
    

    2.3 Ajax 发送POST请求

    1. 在和form表单一块用的时候,form表单里不能写button 和input type="submit",因为在form表单里都是提交,和ajax一块用时form提交一次,ajax再提交一次,就会有问题。所以在form表单中使用<input type='button'>, 要么不用form表单
    

    示例: 利用数据库验证登录用户名和密码,成功跳转到别的网站上,不成功提示验证失败:

    HTML代码:

    <div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <form>
                    username:<input type="text" id="user" class="form-control">
                    password:<input type="password" id="pwd" class="form-control">
                    <input type="button" id="btn" value="提交" class="btn btn-success"><span id="sp1" ></span>
                </form>
            </div>
        </div>
    </div>
    
    <script>
        $('#btn').click(function (){
           var username=$("#user").val();  # 取用户的输入
           var password=$("#pwd").val();
    
           console.log(username, password);
    
           $.ajax({
                url:"",
                method:"post",
                data:{username:username, password:password},
                success:function (DATA){
                    if (DATA.status == 100){   # 看返回值是不是设置的成功的状态码,
                        location.href="https://www.jd.com"
                    }
                    else {# 不是的话则在后面添加提示信息。
                        $("#sp1").html(DATA.msg).css({'color':'red'})
                    }
                }
    
           })
        })
    
    </script>
    
    </body>
    

    后端代码:

    views.py
    
    def login(request):
        if request.is_ajax():
            name = request.POST.get('username')
            pwd = request.POST.get('password')
            from lib01 import models
            res = models.UserVerfiy.objects.filter(username=name, password=pwd)
            print(res)
            data_dict = {'status':100, 'msg':None}
            if res:
                data_dict['msg']="验证成功"
            else:
                data_dict['status']=101
                data_dict['msg'] = "验证失败"
    
            return JsonResponse(data_dict)
        return render(request,"login.html")
    

    3. Ajax上传文件

    HTTP的POST请求有三种编码格式:
        urlencoded: 默认  可以使用request.POST取值
        form-data: 上传文件,可以使用request.POST取值
        json: ajax发送json格式数据,不可以使用request.POST取值
            
    使用Ajax和form表单,默认都是urlencoded格式
    
    如果上传文件: form表单指定格式(enctype="multipart/form-data")
    如果编码方式为urlencoded格式,在body中格式:
    user=xxx&password=xxx   
    

    使用Ajax上传文件:

    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <p>Ajax上传文件</p>
                <input type="file" id="f1">
                <button id="f2" class="btn btn-success">提交</button>
                </form>
            </div>
        </div>
    </div>
    
    <script>
        $("#f2").click(function (){
            var filedata=new FormData() //实例化得到一个目标FormData对象
            //filedata.append('name',$('#f1').val()) //追加一个name对应的值
            var upFile=$('#f1')[0].files[0]
            filedata.append('myfile',upFile) // 追加文件
            $.ajax({
                url:"",
                type:"post",
                //上传文件加上下面两行
                processData:false,  //不预处理数据
                contentType:false,  // 不指定编码,FormData默认是formdata格式
                data: filedata,
                success:function (data){
                    console.log(data)
                }
            })
        })
    </script>
    </body>
    

    views.py

    from django.shortcuts import render,HttpResponse
    from django.http import  JsonResponse
    def index(request):
        if request.is_ajax():
            myfile = request.FILES.get('myfile')
            print(type(myfile))
            with open(myfile.name, 'wb') as f:
                for i in myfile:
                    f.write(i)
    
            return HttpResponse("上传成功")
        return render(request, 'index.html')    
    

    4. Ajax提交Json格式

    使用ajax提交json格式的数据,要指定编码格式:

    contentType:'application/json'

    在前端指定编码格式,后端收到后要反序列出来,才能使用。

     $.ajax({
                url:"",
                type:"post",
                contentType:'application/json',  // 指定编码,才能向后端发json格式
         //序列化成json格式
         		 filedata = JSON.stringify(name:$('#id1').val(),password:$('id2').val())
                data: filedata,
                success:function (data){
                    console.log(data)
                }
            })
    

    views.py

    后端处理,拿到数据后要先反序列化:
        import json
        # request.get默认是取不出来json格式的。使用request.body来取出:
        filedata = request.body
        file_json = json.loads(filedata)
        name = file_json.get('name')
        password = file_json.get('password')
        retrun HttpsRespone("OK")
    

    5. Django内置序列化

    5.1 内置序列化

    把对象转成json格式字符串,目前要做序列化要自己循环,然后拼一个字典,再去序列化成json格式

    from django.core import serializers
    def book_list(request):
        book_list=models.Book.objects.all()
        res = serializers.serialize('json', book_list)
        return HttpResponse(res)
    

    5.2 批量插入数据

    def add_book():
        book_list =[]
        for i in range(1000):
            book=models.Books(name="图书名%s"%i, price="价格%s" %i)
            book_list.append(book)
    
        models.Books.objects.bulk_create(book_list,batch_size=100)
        # batch_size 每次插入多少
    
        
    使用faker模块生成测试数据:
    pip3 install faker
    
    >>> from faker import Faker
    >>> faker = Faker('zh_CN')
    >>> print(faker.name())
    田岩
    >>> print(faker.name())
    黄柳
    >>> print(faker.address())
    云南省婷县锡山汕尾街V座 503156
    >>> print(faker.phone_number())
    13996473292
    >>> print(faker.phone_number())
    18959779669
    

    6. Ajax结合layer弹窗实现二次确认

    6.1 ajax常用参数

    1.url:
      要求为String类型的参数,(默认为当前页地址)发送请求的地址。

    2.type:
      要求为String类型的参数,请求方式(post或get)默认为get。注意其他http请求方法,例如put和delete也可以使用,但仅部分浏览器支持。

    3.timeout:
      要求为Number类型的参数,设置请求超时时间(毫秒)。此设置将覆盖$.ajaxSetup()方法的全局设置。

    4.async:
      要求为Boolean类型的参数,默认设置为true,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为false。注意,同步请求将锁住浏览器,用户其他操作必须等待请求完成才可以执行。

    5.cache:
      要求为Boolean类型的参数,默认为true(当dataType为script时,默认为false),设置为false将不会从浏览器缓存中加载请求信息。

    6.data:
      要求为Object或String类型的参数,发送到服务器的数据。如果已经不是字符串,将自动转换为字符串格式。get请求中将附加在url后。防止这种自动转换,可以查看  processData(防止自动转换)选项。对象必须为key/value格式,例如{foo1:"bar1",foo2:"bar2"}转换为&foo1=bar1&foo2=bar2。如果是数组,JQuery将自动为不同值对应同一个名称。例如{foo:["bar1","bar2"]}转换为&foo=bar1&foo=bar2。

    7.dataType:
      要求为String类型的参数,预期服务器返回的数据类型。如果不指定,JQuery将自动根据http包mime信息返回responseXML或responseText,并作为回调函数参数传递。可用的类型如下:
      xml:返回XML文档,可用JQuery处理。
      html:返回纯文本HTML信息;包含的script标签会在插入DOM时执行。
      script:返回纯文本JavaScript代码。不会自动缓存结果。除非设置了cache参数。注意在远程请求时(不在同一个域下),所有post请求都将转为get请求。
      json:返回JSON数据。
      jsonp:JSONP格式。使用SONP形式调用函数时,例如myurl?callback=?,JQuery将自动替换后一个“?”为正确的函数名,以执行回调函数。
      text:返回纯文本字符串。

    8.beforeSend:
      这个参数主要是为了在向服务器发送请求前,执行一些操作。要求为Function类型的参数,发送请求前可以修改XMLHttpRequest对象的函数,例如添加自定义HTTP头。在beforeSend中如果返回false可以取消本次ajax请求。XMLHttpRequest对象是惟一的参数。
    function(XMLHttpRequest){undefined
    this; //调用本次ajax请求时传递的options参数
    }
    9.complete:
      要求为Function类型的参数,请求完成后调用的回调函数(请求成功或失败时均调用)。参数:XMLHttpRequest对象和一个描述成功请求类型的字符串。
    function(XMLHttpRequest, textStatus){undefined
    this; //调用本次ajax请求时传递的options参数
    }

    10.success:

      要求为Function类型的参数,请求成功后调用的回调函数,有两个参数。
    (1)由服务器返回,并根据dataType参数进行处理后的数据。
    (2)描述状态的字符串。
    function(data, textStatus){undefined
    //data可能是xmlDoc、jsonObj、html、text等等
    this; //调用本次ajax请求时传递的options参数
    }

    11.error:
    要求为Function类型的参数,请求失败时被调用的函数。该函数有3个参数,即XMLHttpRequest对象、错误信息、捕获的错误对象(可选)。ajax事件函数如下:
    function(XMLHttpRequest, textStatus, errorThrown){undefined
    //通常情况下textStatus和errorThrown只有其中一个包含信息
    this; //调用本次ajax请求时传递的options参数
    }

    12.contentType:
    要求为String类型的参数,当发送信息至服务器时,内容编码类型默认为"application/x-www-form-urlencoded"。该默认值适合大多数应用场合。

    13.dataFilter:
    要求为Function类型的参数,给Ajax返回的原始数据进行预处理的函数。提供data和type两个参数。data是Ajax返回的原始数据,type是调用jQuery.ajax时提供的dataType参数。函数返回的值将由jQuery进一步处理。
    function(data, type){undefined
    //返回处理后的数据
    return data;
    }

    14.dataFilter:
    要求为Function类型的参数,给Ajax返回的原始数据进行预处理的函数。提供data和type两个参数。data是Ajax返回的原始数据,type是调用jQuery.ajax时提供的dataType参数。函数返回的值将由jQuery进一步处理。
    function(data, type){undefined
    //返回处理后的数据
    return data;
    }

    15.global:
    要求为Boolean类型的参数,默认为true。表示是否触发全局ajax事件。设置为false将不会触发全局ajax事件,ajaxStart或ajaxStop可用于控制各种ajax事件。

    16.ifModified:
    要求为Boolean类型的参数,默认为false。仅在服务器数据改变时获取新数据。服务器数据改变判断的依据是Last-Modified头信息。默认值是false,即忽略头信息。

    17.jsonp:
    要求为String类型的参数,在一个jsonp请求中重写回调函数的名字。该值用来替代在"callback=?"这种GET或POST请求中URL参数里的"callback"部分,例如{jsonp:'onJsonPLoad'}会导致将"onJsonPLoad=?"传给服务器。

    18.username:
    要求为String类型的参数,用于响应HTTP访问认证请求的用户名。

    19.password:
    要求为String类型的参数,用于响应HTTP访问认证请求的密码。

    20.processData:
    要求为Boolean类型的参数,默认为true。默认情况下,发送的数据将被转换为对象(从技术角度来讲并非字符串)以配合默认内容类型"application/x-www-form-urlencoded"。如果要发送DOM树信息或者其他不希望转换的信息,请设置为false。

    21.scriptCharset:
    要求为String类型的参数,只有当请求时dataType为"jsonp"或者"script",并且type是GET时才会用于强制修改字符集(charset)。通常在本地和远程的内容编码不同时使用。

    6.2 弹窗二次确认

    先要下载layer,地址:https://github.com/sentsin/layer/releases/download/v3.5.1/layer-v3.5.1.zip

    下载后放在项目的static目录,并在settings.py里配置好静态文件目录。

    HTML代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="/static/bootstrap-3.4.1-dist/js/jquery-3.6.0.min.js"></script>
        <script src="/static/bootstrap-3.4.1-dist/js/bootstrap.min.js"></script>
        <link rel="stylesheet" href="/static/bootstrap-3.4.1-dist/css/bootstrap.min.css">
        <script src="/static/layer-v3.5.1/layer/layer.js"></script>  // 导入layer.js
    </head>
    <body>
    
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <table class="table table-hover table-striped">
                    <thead>
                    <tr>
                        <th>ID</th>
                        <th>username</th>
                        <th>passowrd</th>
                        <th>edit</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for foo in userObj %}
                        <tr>
                            <td class="warning">{{ foo.id }}</td>
                            <td class="success">{{ foo.username }}</td>
                            <td class="info">{{ foo.password }}</td>
                            <td class="danger">
                                <a onclick="del_function({{ foo.id }})" id="d_{{ foo.id }}">删除</a>  /*这里a标签里没有href这是为了去掉它自身带的提交功能,还有个方法是: href="javascript:;"*/
                            </td>
                        </tr>
    
                    {% endfor %}
    
                    </tbody>
                </table>
            </div>
        </div>
    </div>
    
    <script>
    
        function del_function(id) {
    
            layer.confirm("确定要删除吗?", {   // 
                    btn: ['确定', '取消'],
                }, function () {
                    $.ajax({
                        url: "",   // 向当前项目提交
                        type: "post",   // 提交方式
                        data: {id: id}, // 把用户的ID传给后面
                        success: function (data) {
                            if (data.static == 200) {  // 后端返回结果,如果等于200则执行成功
                                layer.msg(data.msg,{icon:1},function (){   // icon:1 layer里的图标
                                    location.reload(); // 重新加载页面,否则删除不刷新删除的数据还在页面上
                                })
                            } else {
                                layer.msg(data.msg,{icon:2})
                            }
                        }
                    })
    
                }
            )
    
        }
    </script>
    
    </body>
    </html>
    

    views.py代码:

    from django.shortcuts import render,HttpResponse
    from django.http import  JsonResponse
    # Create your views here.
    from lib01 import models
    
    def userList(request):
    
        res={}
        if request.method == "POST":
            user_id = request.POST.get('id')
            print(user_id, type(user_id))
            user_up = models.UserVerfiy.objects.filter(id=user_id).update(is_delete=1)
            print(user_id, type(user_id))
            if user_up:
                res['static']=200
                res['msg']="删除成功"
            else:
                res['static']=400
                res['msg']="删除失败"
            return JsonResponse(res)
    
        userObj = models.UserVerfiy.objects.filter(is_delete=0).all()
        return render(request, "userlist.html", locals())
    
    

    urls.py路由:

    from django.contrib import admin
    from django.urls import path
    from lib01 import views
    
    urlpatterns = [
        path('userlist/', views.userList),
    ]
    

    7. 分页

    HTML代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="/static/bootstrap-3.4.1-dist/js/bootstrap.min.js"></script>
        <script src="/static/bootstrap-3.4.1-dist/js/jquery-3.6.0.min.js"></script>
        <link rel="stylesheet" href="/static/bootstrap-3.4.1-dist/css/bootstrap.min.css">
    
    </head>
    <body>
    <div class="container-fluid">
        <div class="row">
    
            <div class="col-md-8 col-md-offset-2">
                <div class="panel panel-success">
                    <div class="panel-heading">
                        <h3 class="panel-title">用户信息</h3>
                    </div>
                    <div class="panel-body">
    
                        <table class="table table-striped">
                            <thead>
                            <tr>
                                <th>ID</th>
                                <th>Name</th>
                                <th>Address</th>
                                <th>Phone</th>
                            </tr>
                            </thead>
                            <tbody>
                            {% for user in Page.object_list %}
                                <tr>
                                    <td class="info">{{ user.id }}</td>
                                    <td class="success">{{ user.name }}</td>
                                    <td class="warning">{{ user.address }}</td>
                                    <td class="danger">{{ user.iphone }}</td>
                                </tr>
                            {% endfor %}
    
                            </tbody>
                        </table>
                        <div class="text-center">
                            <nav aria-label="Page navigation">
                                <ul class="pagination">
                                {% if Page.has_previous %}
                                    <!--检查是否有上一页-->
                                    <li>
                                            <a href="/userlist/?page={{ Page.previous_page_number }}"
                                               aria-label="Previous">
                                                <span aria-hidden="true">&laquo;</span>
                                            </a>
                                    </li>
                                {% else %}
                                    <!--如果没有上一页则把上一页按钮禁用-->
                                    <li class="disabled">
                                            <a href="" aria-label="Previous">
                                                <span aria-hidden="true">&laquo;</span>
                                            </a>
                                    </li>
                                {% endif %}
    
                                    <!--分的页数-->
                                    {% for foo in page_range %}
                                        {% if current_num == foo %}
                                            <!--选中哪个页数那个页数就变色-->
                                            <li class="active"><a href="/userlist/?page={{ foo }}">{{ foo }}</a></li>
                                        {% else %}
                                            <li><a href="/userlist/?page={{ foo }}">{{ foo }}</a></li>
                                        {% endif %}
    
                                    {% endfor %}
    
                                    {% if Page.has_next %}
                                         <!--检查是否有下一页-->
                                        <li>
                                            <a href="/userlist/?page={{ Page.next_page_number }}" aria-label="Next">
                                                <span aria-hidden="true">&raquo;</span>
                                            </a>
                                        </li>
                                    {% else %}
                                        <!--如果没有下一页则把下一页按钮禁用-->
                                        <li class="disabled">
                                            <a href="" aria-label="Next">
                                                <span aria-hidden="true">&raquo;</span>
                                            </a>
                                        </li>
                                    {% endif %}
    
                                </ul>
                            </nav>
                        </div>
    
                    </div>
                </div>
    
    
            </div>
        </div>
    
    
    </div>
    
    
    <div>
    
    
    </div>
    
    </body>
    </html>
    

    后端代码:views.py

    from django.shortcuts import render
    
    # Create your views here.
    
    from pagination import  models
    from django.core.paginator import Paginator
    def userlist(request):
        
        user_obj = models.UserList.objects.all().order_by('id') 
        
        current_num = int(request.GET.get("page",1))  # 获取当前页面的页数
        paginator = Paginator(user_obj,50)
        """
        Paginator(user_obj,50) 使用这个方法数据库那必须加.order_by() 否则会报错,报错信息:
        UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list: <class 'pagination.models.UserList'> QuerySet.   paginator = Paginator(user_obj,50)
        """
        
    
        # 使用的try的目的是如果人为的让page等于一个超过范围的数,让它默认在第一页
        try:
            # 分页的page的对象和方法
            Page = paginator.page(current_num)
        except Exception as e:
            current_num = 1
            Page = paginator.page(current_num)
    
        
    
        #  做成一个左5 右5 的分页
    
        if paginator.num_pages >11:
            # 如果总页数大于11,
            # 当前页减5个是不是小于1, 小于1的话显示1到11个。
            if current_num - 5 < 1:
                page_range = range(1,12)
            # 当前页加5个是不是大于总页数, 大于总页数的话显示则显示最后11个。
            elif current_num + 5 > paginator.num_pages:
                page_range = range(paginator.num_pages - 10, paginator.num_pages +1)
            # 上面的都不符合则直接显示当前页前五个,和当前页后5个
            else:
                page_range = range(current_num-5,current_num+6)
        else:
            # 如果总页数小于11则直接显示
            page_range = paginator.page_range
        return  render(request, "userlist.html", locals())
    
    
    
    
    
    
    
    paginator = Paginator(user_obj,50) # 每一页显示的条数,这里显示50条
    # 分页的属性:
    print(paginator.count) # 数据总条数
    print(paginator.num_pages) # 总页数
    print(paginator.per_page) # 每页显示条数
    print(paginator.page_range) # 取范围 range(1, 21)
    print(paginator.page(1)) # 反回一个页的对象, 数字为几则拿第几页的数据
    
    Page = paginator.page(current_num)
    print(Page.has_next()) # 是否有下一页
    print(Page.next_page_number()) # 下一页的页码数
    print(Page.has_previous()) # 是否有上一页
    print(Page.previous_page_number()) # 上一页的页码数
    print(Page.object_list)  # 当前页的
    print(Page.number)  # 当前的页码
    
  • 相关阅读:
    uni-app:实现时钟自走(动态时钟效果)
    Android的FragmentManager介绍以及它管理Fragment的流程
    linux入门---信号的操作
    Spring篇---第八篇
    【selenium4自动化工具的使用以及Junit5单元测试框架】
    华为云服务器实例测评
    弱网神器:quic-tun(在存在丢包的网络环境中成倍的提升 TCP 性能)
    Spring事务
    pdffactory pro 8中文破解版
    羊驼笔记:清算bot
  • 原文地址:https://www.cnblogs.com/hans-python/p/16022690.html