从小白到小黑 python学习之旅 日常总结 67(django 框架 Ajax 批量插入 分页器)

前后端传输数据的编码格式(contentType)

"""
前后端传输数据的编码格式
    urlencoded
    
    formdata
    
    json
"""

 

"""
get请求数据就是直接放在url后面的
url?username=jason&password=123
"""

# 我们主要研究post请求数据的编码格式
# 可以朝后端发送post请求的方式
    """
    1.form表单
    2.ajax请求
    """

# 研究form表单
默认的数据编码格式是urlencoded
数据格式(编码格式):username=jason&password=123
    django后端针对 符合urlencoded编码格式的数据 都会自动帮你解析封装到request.POST中
      username=jason&password=123    >>> request.POST
  
  如果你把编码格式改成formdata,那么针对普通的键值对还是解析到request.POST中而将文件解析到request.FILES中
  
  form表单是没有办法发送json格式数据的
 

# 研究ajax
默认的编码格式也是urlencoded
数据格式(编码格式):username=jason&age=20
    django后端针对 符合urlencoded编码格式的数据 都会自动帮你解析封装到request.POST中
      username=jason&age=20    >>> request.POST

 

 

ajax发送json格式数据

 

// 前端
<script>
    $('#d1').click(function () {
        $.ajax({
            url:'',
            type:'post',
            // 前后端传输数据的时候一定要确保编码格式跟数据真正的格式是一致的
            data:JSON.stringify({'username':'jason','age':25}),
            contentType:'application/json',  // 指定编码格式
            success:function () {

            }
        })
    })
</script>

 

 

# 后端
import json
def ab_json(request):
"""
request对象方法补充
    request.is_ajax()
        判断当前请求是否是ajax请求 返回布尔值
"""
    if request.is_ajax():
        #django后端不会帮你处理json格式数据需要你自己去request.body获取并处理
        json_bytes = request.body

        #json_str = json_bytes.decode('utf-8')
        #json_dict = json.loads(json_str)

        # json.loads括号内如果传入了一个二进制格式的数据那么内部自动解码再反序列化
        json_dict = json.loads(json_bytes)

    return render (request,'ad_json.html')

 

"""
ajax发送json格式数据需要注意点
    1.contentType参数指定成:application/json
    2.数据是真正的json格式数据
    3.django后端不会帮你处理json格式数据需要你自己去request.body获取并处理
""" 

ajax发送文件

"""
ajax发送文件需要借助于js内置对象FormData
"""

 

//前端
<script>
    // 点击按钮朝后端发送普通键值对和文件数据
    $('#d4').on('click',function () {
        
        // 1 需要先利用FormData内置对象
        let formDateObj = new FormData();
        
        // 2 添加普通的键值对
        formDateObj.append('username',$('#d1').val());
        formDateObj.append('password',$('#d2').val());
        
        // 3 添加文件对象
        formDateObj.append('myfile',$('#d3')[0].files[0])
        
        // 4 将对象基于ajax发送给后端
        $.ajax({
            url:'',
            type:'post',
            data:formDateObj,  // 直接将对象放在data后面即可

            // ajax发送文件必须要指定的两个参数
            contentType:false,  // 不需使用任何编码 django后端能够自动识别formdata对象
            processData:false,  // 告诉你的浏览器不要对你的数据进行任何处理

            success:function (args) {
            }
        })
    })
</script>
#后端
def ab_file(request):
    if request.is_ajax():
        if request.method == 'POST':
            print(request.POST)
            print(request.FILES)
    return render(request,'ab_file.html')

 

"""
总结:
    1.需要利用内置对象FormData
         可以添加普通的键值对
          也可以添加文件对象

    2.需要指定两个关键性的参数
        contentType:false,  // 不需使用任何编码 django后端能够自动识别formdata对象
        processData:false,  // 告诉你的浏览器不要对你的数据进行任何处理
    
  3.django后端能够直接识别到formdata对象并且能够将内部的普通键值自动解析并封装到request.POST中 文件数据自动解析并封装到request.FILES中
"""

 

django自带的序列化组件(drf做铺垫)

"""
如果发现你可以直接使用MySQL但是无法使用sqlite3
不要慌张不要恐惧 你只需要按照之前MySQL的操作将sqlite3的驱动装一下即可
"""

 

# 需求:在前端 获取到后端用户表里面所有的数据 并且要是列表套字典
import json
from django.http import JsonResponse
from django.core import serializers
def ab_ser(request):
    user_queryset = models.User.objects.all()
    
    # 手动改成列表套字典
    # [{},{},{},{},{}]
    # user_list = []
    # for user_obj in user_queryset:
    #     tmp = {
    #         'pk':user_obj.pk,
    #         'username':user_obj.username,
    #         'age':user_obj.age,
    #         'gender':user_obj.get_gender_display()
    #     }
    #     user_list.append(tmp)
    # return JsonResponse(user_list,safe=False)
    # return render(request,'ab_ser.html',locals())
"""
[
 {"pk": 1, "username": "jason", "age": 25, "gender": "male"}, 
 {"pk": 2, "username": "egon", "age": 31, "gender": "female"},
 {"pk": 3, "username": "kevin", "age": 32, "gender": "others"}, 
 {"pk": 4, "username": "tank", "age": 40, "gender": 4}
 ]
前后端分离的项目
    作为后端开发  只需要写代码将数据处理好
    能够序列化返回给前端即可 
        再写一个接口文档 告诉前端每个字段代表的意思即可
"""
  
    
    # 序列化  serializers
    res = serializers.serialize('json',user_queryset)
    """会自动帮你将数据变成json格式的字符串 并且内部非常的全面"""
    return HttpResponse(res)
"""                
[
{   "model": "app01.user", 
    "pk": 1, 
    "fields": {"username": "jason", "age": 25, "gender": 1}}, 
    
{   "model": "app01.user", 
    "pk": 2, 
    "fields": {"username": "egon", "age": 31, "gender": 2}}, 
    
{   "model": "app01.user", 
    "pk": 3, 
    "fields": {"username": "kevin", "age": 32, "gender": 3}},
     
{   "model": "app01.user", 
    "pk": 4, 
    "fields": {"username": "tank", "age": 40, "gender": 4}}
]
写接口就是利用序列化组件渲染数据然后写一个接口文档 该交代交代一下就完事
"""

 

ajax结合sweetalert

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <style>
        div.sweet-alert h2 {
            padding-top: 10px;
        }
    </style>
    {% load static %}
    <link rel="stylesheet" href="{% static 'dist/sweetalert.css' %}">
    <script src="{% static 'dist/sweetalert.min.js' %}"></script>
    {#    关于静态文件查找 其实还有一个方法 代码发布再透露   #}
</head>
<body>
<div class="container-fluid">
    <h1 class="text-center">数据展示</h1>
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <table class="table-striped table table-hover">
                <thead>
                    <tr>
                        <th>ID</th>
                        <th>username</th>
                        <th>age</th>
                        <th>gender</th>
                        <th>actions</th>
                    </tr>
                </thead>
                <tbody>
                    {% for user_obj in user_queryset %}
                        <tr>
                            <td>{{ user_obj.pk }}</td>
                            <td>{{ user_obj.username }}</td>
                            <td>{{ user_obj.age }}</td>
                            <td>{{ user_obj.get_gender_display }}</td>
                            <td>
                                <button class="btn btn-primary btn-xs">编辑</button>
                                <button class="btn btn-danger btn-xs del" delete_id="{{ user_obj.pk }}">删除</button>
                            </td>
                        </tr>
                    {% endfor %}

                </tbody>
            </table>
        </div>
    </div>
</div>

<script>
    $('.del').on('click',function () {
        // 先将当前标签对象存储起来
        let currentBtn = $(this);
        // 二次确认弹框
        swal({
          title: "你确定要删吗?",
          text: "你可要考虑清除哦,可能需要拎包跑路哦!",
          type: "warning",
          showCancelButton: true,
          confirmButtonClass: "btn-danger",
          confirmButtonText: "是的,老子就要删!",
          cancelButtonText: "算了,算了!",
          closeOnConfirm: false,
          closeOnCancel: false,
          showLoaderOnConfirm: true
        },
        function(isConfirm) {
          if (isConfirm) {
                // 朝后端发送ajax请求删除数据之后 再弹下面的提示框
                $.ajax({
                    {#url:'/delete/user/' + currentBtn.attr('delete_id'),  // 1 传递主键值方式1#}
                    url:'/delete/user/',  // 2 放在请求体里面
                    type:'post',
                    data:{'delete_id':currentBtn.attr('delete_id')},
                    success:function (args) {  // args = {'code':'','msg':''}
                        // 判断响应状态码 然后做不同的处理
                        if(args.code === 1000){
                            swal("删了!", args.msg, "success");
                            // 1.lowb版本 直接刷新当前页面
                            {#window.location.reload()#}
                            // 2.利用DOM操作 动态刷新
                            currentBtn.parent().parent().remove()
                        }else{
                            swal('完了','出现了位置的错误','info')
                        }
                    }

                })

          } else {
            swal("怂逼", "不要说我认识你", "error");
          }
        });
    })

</script>
</body>
</html>
前端
def user_list(request):
    user_queryset = models.User.objects.all()
    return render(request,'user_list.html',locals())

import time
def delete_user(request):
    """
    前后端在用ajax进行交互的时候 后端通常给ajax的回调函数返回一个字典格式的数据
    :param request:
    :return:
    """
    if request.is_ajax():
        if request.method == 'POST':
            back_dic = {"code":1000,'msg':''}
            time.sleep(3)  # 模拟操作数据的延迟
            delete_id = request.POST.get('delete_id')
            models.User.objects.filter(pk=delete_id).delete()
            back_dic['msg'] = '数据已经删了,你赶紧跑路!'
            # 我们需要告诉前端我们操作的结果
            return JsonResponse(back_dic)
后端

 

 

批量插入

def ab_pl(request):
    # 先给Book插入一万条数据
    # for i in range(10000):
    #     models.Book.objects.create(title='第%s本书'%i)
    # # 再将所有的数据查询并展示到前端页面
    # book_queryset = models.Book.objects.all()

    # 批量插入
     book_list = []
     for i in range(100000):
         book_obj = models.Book(title='第%s本书'%i)
         book_list.append(book_obj)
     models.Book.objects.bulk_create(book_list)
    """
    当你想要批量插入数据的时候 使用orm给你提供的bulk_create能够大大的减少操作时间
    :param request: 
    :return: 
    """
    return render(request,'ab_pl.html',locals())

 

分页器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
{% for book_obj in book_queryset %}
    <p>{{ book_obj.title }}</p>
    <nav aria-label="Page navigation">

</nav>

{% endfor %}
<ul class="pagination">
    <li>
      <a href="#" aria-label="Previous">
        <span aria-hidden="true">&laquo;</span>
      </a>
    </li>
    {{ page_html|safe }}
    <li>
      <a href="#" aria-label="Next">
        <span aria-hidden="true">&raquo;</span>
      </a>
    </li>
  </ul>

</body>
</html>
内部分析 前端
def ab_pl(request):
    # 先给Book插入一万条数据
    # for i in range(10000):
    #     models.Book.objects.create(title='第%s本书'%i)
    # # 再将所有的数据查询并展示到前端页面
    # book_queryset = models.Book.objects.all()

    # 批量插入
    # book_list = []
    # for i in range(100000):
    #     book_obj = models.Book(title='第%s本书'%i)
    #     book_list.append(book_obj)
    # models.Book.objects.bulk_create(book_list)
    """
    当你想要批量插入数据的时候 使用orm给你提供的bulk_create能够大大的减少操作时间
    :param request: 
    :return: 
    """

    # 分页
    book_list = models.Book.objects.all()

    # 想访问哪一页
    current_page = request.GET.get('page',1)  # 如果获取不到当前页码 就展示第一页
    # 数据类型转换
    try:
        current_page = int(current_page)
    except Exception:
        current_page = 1
    # 每页展示多少条
    per_page_num = 10
    # 起始位置
    start_page = (current_page - 1) * per_page_num
    # 终止位置
    end_page = current_page * per_page_num

    # 计算出到底需要多少页
    all_count = book_list.count()

    page_count, more = divmod(all_count, per_page_num)
    if more:
        page_count += 1

    page_html = ''
    xxx = current_page
    if current_page < 6:
        current_page = 6
    for i in range(current_page-5,current_page+6):
        if xxx == i:
            page_html += '<li class="active"><a href="?page=%s">%s</a></li>'%(i,i)
        else:
            page_html += '<li><a href="?page=%s">%s</a></li>'%(i,i)



    book_queryset =  book_list[start_page:end_page]
    return render(request,'ab_pl.html',locals())
"""
per_page_num = 10
current_page                start_page                  end_page
    1                           0                           10
    2                           10                          20
    3                           20                          30
    4                           30                          40


per_page_num = 5
current_page                start_page                  end_page
    1                           0                           5
    2                           5                           10
    3                           10                          15
    4                           15                          20
    
start_page = (current_page - 1) * per_page_num
end_page = current_page * per_page_num
"""
内部分析 后端

 

posted @ 2020-06-03 17:26  It's_cool  阅读(122)  评论(0)    收藏  举报