zoukankan      html  css  js  c++  java
  • ajax

    一、多对多的三种创建方式

    1、三种方式

      1、全自动(较为常用)

      2、纯手动(了解)

      3、半自动(推荐使用)

    2、优缺点比较

      1、全自动:

        优点:第三张表自动帮你创建

        缺点:第三张表无法扩展额外的字段

      2、纯手动:

        优点:第三张表可以扩展额外的字段

        缺点:orm查询的时候会带来不便

      3、半自动:

        优点:第三张表可以扩展任意的额外字段 还可以利用orm 的正反向查询

        缺点:无法利用 add set remove clear方法,但是虽然你无法使用 你还可以自己直接操作第三张表,所以推荐使用半自动

    3、简易代码演示

    # 全自动
    
    class Book(models.Model):
        title = models.CharField(max_length=32)
        authors = models.ManyToManyField(to='Author')  # 第三方表orm帮我们创建
    
    
    class Author(models.Model):
        name = models.CharField(max_length=32)
    
    
    # 纯手动
    class Book(models.Model):
        title = models.ManyToManyField(max_length=32)
    
    
    class Author(models.Model):
        name = models.CharField(max_length=32)
    
    
    class Book2Author(models.Model):
        book = models.ForeignKey(to='Book')     # 书的外键字段,注意此时后面不用加_id因为django的orm会自动添加
        author = models.ForeignKey(to='Author')   # 作者表的外键字段,注意此时后面不用加_id因为django的orm会自动添加
        create_time = models.DateField(auto_now_add=True)
    
    
    # 半自动
    class Book(models.Model):
        title = models.ManyToManyField(max_length=32)
        authors = models.ManyToManyField(to='Author', through='Book2Author', through_fields=('book', 'author'))
        # 注意:多对多外键字段创在哪一方都可以,上面的这句话的意思是,告诉orm第三张表你不用帮我创了,我已经创好了through='Book2Author',告诉他我的第三张表是哪一个,
        #  through_fields=('book', 'author')是告诉orm我的哪两个字段是外键字段,然后你去给我绑定关系即可,因为字段可能有多个
    
    
    class Author(models.Model):
        name = models.CharField(max_length=32)
        books = models.ManyToManyField(to='Book', through='Book2Author', through_fields=('author', 'book'))    # 这是外键字段绑在作者表上的写法,
        # 总结:在那张下面绑定,through_fields=()中第一个参数就写那张表
    class Book2Author(models.Model): book = models.ForeignKey(to='Book') # 书的外键字段,注意此时后面不用加_id因为django的orm会自动添加 author = models.ForeignKey(to='Author') # 作者表的外键字段,注意此时后面不用加_id因为django的orm会自动添加 create_time = models.DateField(auto_now_add=True)

    二、Ajax

    1、Ajax特点简单介绍(八个字)

      异步提交

        同步:任务提交之后原地等待任务返回的结果  从进程表现上来说   就好像是阻塞

        异步:任务提交之后不需要原地等地等待返回结果  直接执行下一行代码  从进程表现上来说   非阻塞

      局部刷新

    2、Ajax简介

      AJAXAsynchronous Javascript And XML)翻译成中文就是异步的JavascriptXML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。

      AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

      AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

    AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

    • 整个过程中页面没有刷新,只是刷新页面中的局部位置而已!
    • 当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!

    3、Ajax常见应用场景

      搜索引擎根据用户输入的关键字,自动提示检索关键字。

      还有一个很重要的应用场景就是注册时候的用户名的查重。

      其实这里就使用了AJAX技术!当文件框发生了输入变化时,使用AJAX技术向服务器发送一个请求,然后服务器会把查询到的结果响应给浏览器,最后再把后端返回的结果展示出来

    • 整个过程中页面没有刷新,只是局部刷新了;
    • 在请求发出后,浏览器不用等待服务器响应结果就可以进行其他操作;

    4、Ajax优缺点

    优点:

    • AJAX使用JavaScript技术向服务器发送异步请求;
    • AJAX请求无须刷新整个页面;
    • 因为服务器响应内容不再是整个页面,而是页面中的部分内容,所以AJAX性能高; 
    • 两个关键点:1.局部刷新,2.异步请求

    5、与后端进行交互的方式

      1、浏览器窗口输入url    然后回车                           GET

      2、a标签href属性填写url    点击                              GET

      3、form表单                                                            GET/POST

      4、Ajax                     GET/POST

      注意: Ajax并不是一门语言  它其实就是基于js写的一个功能模块而已

         由于原生的js书写Ajax较为繁琐,所以这里我们直接学jQuery封装好的Ajax模块操作

    三、初始Ajax以及Ajax的基本语法结构

    1、一个小案列初始Ajax

      需求:页面上有三个input框   一个按钮   用户在前面两个框中输入数字   点击按钮保证页面不刷新的情况下,

         将数据发送给后端做计算,再将计算好的结果发送给前端展示到第三个input框中。

    """day55 URL Configuration
    
    The `urlpatterns` list routes URLs to views. For more information please see:
        https://docs.djangoproject.com/en/1.11/topics/http/urls/
    Examples:
    Function views
        1. Add an import:  from my_app import views
        2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
    Class-based views
        1. Add an import:  from other_app.views import Home
        2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
    Including another URLconf
        1. Import the include() function: from django.conf.urls import url, include
        2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
    """
    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^index/', views.index),
    ]
    urls.py
    from django.shortcuts import render, HttpResponse, redirect, reverse
    
    # Create your views here.
    
    def index(request):
        if request.method == 'POST':   # 因为是post请求所以需要去把配置文件中中间件的第四行注释掉
            i1 = request.POST.get('i1')
            i2 = request.POST.get('i2')
    
            # 注意现在i1和i2是字符串类型  需要先做类型转换
            i3 = int(i1) + int(i2)
            return HttpResponse(i3)
        return render(request, 'index.html')
    Views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    
    </head>
    <body>
    <input type="text" id="i1"> + <input type="text" id="i2"> = <input type="text" id="i3">
    <button id="d1">按钮</button>
    
    
    {#{* 给按钮添加绑定事件 *}#}
    <script>
        $('#d1').click(function () {
            //获取两个框的内容 朝后端提交异步请求
    
            // ajax基本语法
            $.ajax({
                //1、到底朝那个后端提交数据
                url:'',  //控制数据的提交路径   也有三种写法跟form表单的action属性一致
                //2、指定当前的请求方式
                type:'post',
                //3、指定提交的数据
                data:{'i1':$('#i1').val(), 'i2':$('#i2').val()},
                //4、ajax是异步提交 所以需要给一个回调函数来处理返回的结果
                success:function (data) {//固定接收一个形参data  data就是异步提交的返回结果
                    {#alert(data)#}
                    //将异步回调的结果通过DOM操作渲染到第三个input框中
                    $('#i3').val(data)
                }
            })
        })
    </script>
    </body>
    </html>
    index.html

    - 演示图

     2、ajax基本语法结构

    // ajax基本语法
            $.ajax({
                //1、到底朝那个后端提交数据
                url:'',  //控制数据的提交路径   也有三种写法跟form表单的action属性一致
                //2、指定当前的请求方式
                type:'post',
                //3、指定提交的数据
                data:{'i1':$('#i1').val(), 'i2':$('#i2').val()},
                //4、ajax是异步提交 所以需要给一个回调函数来处理返回的结果
                success:function (data) {//固定接收一个形参data  data就是异步提交的返回结果
                    {#alert(data)#}
                    //将异步回调的结果通过DOM操作渲染到第三个input框中
                    $('#i3').val(data)
                }
            })

    四、content-Type前后端传输数据的编码格式

    1、提交数据的三种编码 格式

      urlencoded

      formdata

      application/json

    2、演示form与ajax的content-Type参数

      a、form 表单

       1、默认是以urlencoded编码格式传输数据

        2、urlencoded的数据格式

         xxx=xxx&yyy=yyy

         django 后端针对该格式的数据,会自动解析帮你打包到request.POST中

        3、formdata数据格式

         django后端针对符合urlencoded编码格式(普通键值对)的数据还是统一解析到request.POST中

         而针对formdata文件数据就会自动解析放到request.FILES中

     b、ajax提交

        1、ajax默认的也是urlencoded编码格式

         2、ajax也可以发送json(这个form表单发送不了)

        注意:前后端数据交互  编码格式与数据格式一定要一致 ,不可以骗人家!!!明明你要发送的是json格式的数据,你跟我吼一声说你要发送列表了。 

          application/json

        django后端针对json格式的数据,并不会做任何的处理,而是直接放到request.body中, 我们也需要掌握ajax发json格式的基本结构代码

    $.ajax({
                 url:'',
                 type:'post',
                 //修改content-Type参数
                 contentType:'application/json',
                 data:JSON.stringify({'username':'yafeng', 'password': 123}),//将数据序列化成json格式数据
                 success:function (data) {
                     alert(data)
                 }
    
             })

        3、ajax发送文件 

          借助于内置对象FormData

          ajax发送文件的基本语法结构

    既发普通键值对也发文件
                // ajax发送文件数据  需要借助于内置对象
                $('#d3').click(function () {
                    // 1 需要先生成一个内置对象
                    var myFormData = new FormData();
                    // 2 传普通键值对  当普通键值对较多的时候 我们可以利用for循环来添加
                    myFormData.append('username','jason');
                    myFormData.append('password',123);
                    // 3 传文件
                    myFormData.append('myfile',$('#i1')[0].files[0]);  // 获取input框内部用户上传的文件对象
                    // 发送ajax请求
                    $.ajax({
                        url:'',
                        type:'post',
                        data:myFormData,
                        // 发送formdata对象需要指定两个关键性的参数
    
                        processData:false,  // 让浏览器不要对你的数据进行任何的操作
                        contentType:false,  // 不要使用任何编码格式 对象formdata自带编码格式并且django能够识别该对象
    
                        success:function (data) {
                            alert(data)
                        }
                    })
                })

    - 代码演示

    """day55 URL Configuration
    
    The `urlpatterns` list routes URLs to views. For more information please see:
        https://docs.djangoproject.com/en/1.11/topics/http/urls/
    Examples:
    Function views
        1. Add an import:  from my_app import views
        2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
    Class-based views
        1. Add an import:  from other_app.views import Home
        2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
    Including another URLconf
        1. Import the include() function: from django.conf.urls import url, include
        2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
    """
    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^index/', views.index),
        url(r'^ab_ct/', views.ab_ct),
    ]
    urls.py
    from django.shortcuts import render, HttpResponse, redirect, reverse
    
    # Create your views here.
    
    def index(request):
        if request.method == 'POST':   # 因为是post请求所以需要去把配置文件中中间件的第四行注释掉
            i1 = request.POST.get('i1')
            i2 = request.POST.get('i2')
    
            # 注意现在i1和i2是字符串类型  需要先做类型转换
            i3 = int(i1) + int(i2)
            return HttpResponse(i3)
        return render(request, 'index.html')
    
    
    import json
    def ab_ct(request):
        if request.method == 'POST':
            # print(request.POST)
            # print(request.FILES)
            # print(request.body)
            # 自己处理json格式的数据
            # 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) # 注:json.loads可以自动帮你解码,所以上面一步可以简写
            # print(json_dict, type(json_dict))
    
    
            print(request.POST)
            print(request.FILES)
        return render(request, 'ab_ct.html')
    Views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    
    </head>
    <body>
    {#<form action="" method="post" enctype="multipart/form-data">#}
    {#    <input type="text" name="username">#}
    {#    <input type="text" name="password">#}
    {#    <input type="file" name="myfile">#}
    {#    <input type="submit">#}
    {#</form>#}
    
    <button id="d1">点击发送ajax请求</button>
    
    <button id="d2">ajax发送json数据格式</button>
    
    <input type="file" name="myfile" id="i1">
    <button id="d3">ajax发送文件数据</button>
    
    <script>
    
        /*ajax 默认格式
        $('#d1').click(function () {
            $.ajax({
                url:'',
                type:'post',
                data:{'username': 'yafeng', 'password': 123},
                success:function (data) {
                    alert(data)
                }
            })
        })
    
         */
    
        //发json格式数据
        /*
        $('#d2').on('click', function () {
             $.ajax({
                 url:'',
                 type:'post',
                 //修改content-Type参数
                 contentType:'application/json',
                 data:JSON.stringify({'username':'yafeng', 'password': 123}),//将数据序列化成json格式数据
                 success:function (data) {
                     alert(data)
                 }
    
             })
        })
    
         */
    
        // ajax发送文件数据需要借助于 内置对象FormData
        $('#d3').click(function () {
            //1、需要先生成一个内置对象
            var myFormDate = new FormData();
            //2、传普通键值对
            myFormDate.append('username','yafeng');
            myFormDate.append('password', 123);
            //3、传文件
            myFormDate.append('myfile', $('#i1')[0].files[0])  //先变成原生json对象  再获取input框内部用户上传的文件对象
            //4、发送ajax请求
            $.ajax({
                url:'',
                type:'post',
                data:myFormDate,
                //发送formdata对象需要指定两个关键字的参数
                processData:false,// 让浏览器不要对你的数据进行任何的操作
                contentType:false,// 不要使用任何编码格式 对象formdata自带编码格式并且django能够识别该对象
    
                success:function (data) {
                    alert(data)
                }
            })
    
        })
        
    </script>
    </body>
    </html>
    ab_ct.html

    五、Django内置的序列化功能

    Django内置的序列功能借助 serializers 模块,可以序列化对象

    以前我们将后端将数据传递给前端通过json序列化

    复制代码
    from app01 import models
    import json
    ​
    def xlh(request):
        book_query = models.Book.objects.all()
        book_list = []
        for book_obj in book_query:
            book_list.append({
                'name': book_obj.name,
                'price': book_obj.price
            })
        res = json.dumps(book_list)
        return render(request, 'xlh.html', locals())
    复制代码

    我们可以使用Django内置的序列化功能模块 serializers ,直接序列化,展示的结果更加多将类名,主键都能拿到

    复制代码
    from django.core import serializers
    ​
    def xlh(request):
        book_query = models.Book.objects.all()
        res = serializers.serialize('json', book_query)
    return HttpResponse(res)
    # [{"model": "app01.book", "pk": 1, "fields": {"name": "jason", "price": "123"}}]
    复制代码

    六、批量插入数据

    我们之前学过的批量插入数据方式通过for循环再利用create方法,但是每次都要走数据库,效率很低

    def insert_data(request):
        for i in range(1,501):
            models.Book.objects.create(name='第%s本书'%i)
        book_query = models.Book.objects.all()
        return render(request, 'insert.html', locals())
      # 每次循环一次都需要去数据库插入一条,500条大约需要一分钟

    我们可以通过先将数据添加到一个列表中再使用 bulk_create 方法插入数据,这样就只会走一次数据库,效率很高

    复制代码
    def insert_data(request):
        book_list = []
        for i in range(1,9999):
            book_list.append(models.Book(name='新添加的第%s书'%i))
        models.Book.objects.bulk_create(book_list)  # 批量插入数据
        book_query = models.Book.objects.all()
        return render(request, 'insert.html', locals())
      # 效率很高,大约1秒插入9999条数据
    复制代码

    七、自定义分页器及使用

    1、先引用分页器组件,封装好的类,存入本地文件夹中

     分页器组件

    后端代码:

    复制代码
    # 获取当前页码,默认为1
    current_page = request.GET.get('page', 1)
    # 获取总页数
    all_count = book_queryset.count()
    # 生成一个自定义分页器类对象
    page_obj=Pagination(current_page=current_page,all_count=all_count,pager_count=9)
    # 针对真实的queryset数据进行切片操作
    page_queryset = book_queryset[page_obj.start:page_obj.end]
    return render(request,'ab_bc.html',locals())
    复制代码

    前端代码:

    {{ page_obj.page_html|safe }}

    八、Ajax结合sweetalert实现删除二次确认

    1、首先需要从sweetalert 连接找到Bootstrap-sweetalert包,将包下载到本地

    我们只需要使用dist文件中的 js 和 css 文件

    2、从sweetalert forBootstrap中找到需要使用的样式,引用其代码

    我们以删除二次确认为例:

    后端代码:

    复制代码
    from django.http import JsonResponse
    import time
    def show_user(request):
        """
        前后端如果是通过ajax进行交互 那么交互的媒介一般情况下都是一个字典
        """
        if request.method == 'POST':
            # 模仿删除等待效果
            time.sleep(3)
            # 定义一个字典,通过Ajax传给后端的data
            back_dic = {"code":1000,'msg':''}
            # 拿到需要删除的数据id
            delete_id = request.POST.get('delete_id')
            # 将数据删除
            models.Userinfo.objects.filter(pk=delete_id).delete()
            back_dic['msg'] = '删除成功,准备跑路!!!'
            # 以json数据格式将字典返回给前端Ajax中的data
            return JsonResponse(back_dic)
        user_queryset = models.Userinfo.objects.all()
        return render(request,'show_user.html',locals())
    复制代码

    前端代码:

    首先需要引入sweetalert文件中的css和js文件

    复制代码
        {% load  static %}
        <link rel="stylesheet" href="{% static 'dist/sweetalert.css' %}">
        <script src="{% static 'dist/sweetalert.min.js' %}"></script>
        {# 删除中文文字宽度不够,找到文字标签修改大小#}
        <style>
            div.sweet-alert h2 {
                padding-top: 10px;
            }
        </style>
    复制代码

    调用sweetalert中样式代码,加以修改

    复制代码
    <script>
        // 给删除按钮绑定点击事件
        $('.cancel').click(function () {
            // 定义变量指代某一条数据
            var $aEle = $(this);
            // 引用sweetalert中的删除样式代码
            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:'',
                            type:'post',
                            data:{'delete_id':$aEle.attr("data_id")},
                            success:function (data) {  // 回调函数会自动将二进制的json格式数据 解码并反序列成js中的数据类型
                                if (data.code == 1000){
                                    swal("删了!", "你准备跑路吧!", "success");
                                    // 方式1  删除后自动刷新网页
                                    // window.location.reload()
                                    // 方式2 DOM操作动态修改,将删除的那条数据移除
                                    $aEle.parent().parent().remove()  // 将标签直接移除
                                }else{
                                    swal('发生了未知的错误', "error");
                                }
                            }
                        });
                        
                    } else {
                        swal("怂笔", "你成功的刷新我对你的认知", "error");
                    }
                });
        })
    </script>
    复制代码

        

      

        

      

  • 相关阅读:
    博客园作业 04
    C语言II博客作业02
    C语言II博客作业01
    linux找不到动态链接库.so文件的解决方法
    工厂模式
    markdown基本语法
    IDEA解决file://无法访问问题,构建虚拟路径方法
    python 制作伪switch(不过认为更加麻烦,使用起来不方便,不如跟随python使用if更轻巧)
    python 读取编码为UTF-8-BOM文件(如果一直出现读取失败,可以尝试用记事本查看文件的编码格式,且可以读取任何文件格式)
    python 读取excel方法(最大行数:1048576)
  • 原文地址:https://www.cnblogs.com/yafeng666/p/12181567.html
Copyright © 2011-2022 走看看