zoukankan      html  css  js  c++  java
  • Django与Ajax

    Django与ajax(入门)

    AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步JavaScript和XML”。是指一种创建交互式,快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。

    通过在后台与服务器进行少量数据交换,AJAX可以使网页实现异步更新,这意味着在不重新加载整个网页页面的情况下,对网页的部分内容进行更新

    AJAX是一种用于快速动态网页的技术

    传统的网页(不使用AJAX)如果需要更新内容,必须重新加载整个页面,而前面谈到AJAX是什么,其主要就是异步提交,那我们来聊聊同步和异步提交的区别

    同步提交:当用户发送请求时,当前页面不可以使用,服务器响应页面到客户端,响应完成,客户才可以使用网页

    异步提交:当用户发送请求时,当前页面可以继续使用,当异步请求的数据响应给页面,页面把数据显示出来

    AJAX的工作原理:

    相当于在用户和服务器之间加了一个中间层(AJAX引擎),使用户操作与服务器响应异步化。并不是所有的用户请求都提交给服务器,像一些数据验证和数据处理等都交给ajax引擎自己来做,只有确定需要从服务器读取数据时再由AJAX引擎代为向服务器提交请求

    客户端发送请求,请求交给xhr,xhr把请求提交给服务,服务器进行业务处理,服务器响应数据交给xhr对象,xhr对象接收数据,由javascript把数据写到页面上,如下图所示:

    要完整实现一个AJAX异步调用和局部刷新,通常需要以下几个步骤:

    1.创建XMLHttpRequest对象,即创建一个异步调用对象.
    2.创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.
    3.设置响应HTTP请求状态变化的函数.
    4.发送HTTP请求.
    5.获取异步调用返回的数据.
    6.使用JavaScript和DOM实现局部刷新.

    ps:AJAX传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)
      基本上web页面都有很多ajax请求

    写ajax跟后端交互

    1 使用原生js写ajax请求(没有人用)
         第一:麻烦
         第二:区分浏览器,需要做浏览器兼容
    2 现在主流做法(现成有人封装好了,jquery,axios..)
        以jquery为例

    通过Ajax,实现前端输入两个数字,服务器做加法,返回到前端页面

    def ajax_test(request):
    
        return render(request,'ajax_test.html')
    
    
    def sum(request):
        import time
        time.sleep(2)
        # 先转成整型再加
        a1=int(request.GET.get('a1')) 
        a2=int(request.GET.get('a2'))
        return HttpResponse(a1+a2)
    视图函数views.py
    urlpatterns = [
         url(r'^ajax_test/',views.ajax_test),
        url(r'^sum/',views.sum),
    ]
    路由urls.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        {% load static %}
        <script src="{% static 'JQuery3.6.0.js' %}"></script>
    
    </head>
    <body>
    <input type="text" id="a1"> + <input type="text" id="a2">=<input type="text" id="sum">
    <button id="btn_submit">计算</button>
    
    </body>
    <script>
        $('#btn_submit').click(function () {
            var a1 = $('#a1').val()
            var a2 = $('#a2').val()
            // 发送ajax请求,计算,返回结果
            $.ajax({
                url: '/sum/',  //ajax请求的地址
                method: 'get',//请求方式
                data: {'a1': a1, 'a2': a2}, //携带参数
                success: function (data) {   //服务端成功返回会回调,执行匿名函数
                    console.log(data)
                    $('#sum').val(data)
                }
            })
    
        })
    
    </script>
    </html>
    ajax_test.html

    1 ajax发送其他请求

    1 大坑
        如果在form表单中,写button和input是submit类型,会触发form表单的提交
        如果不想触发:
            不写在form表单中
            使用input,类型是button
            
    2后端响应格式如果是:html/text格式,ajax接收到数据后需要自己转成对象
        后端响应格式是:json,ajax接收到数据后会自动转成对象
        总结:后端返回数据,统一都用JsonResponse、
        
    3如果使用了ajax,后端就不要返回rediret,render,HttpResponse
        直接返回JsonResponse

    基于Ajax进行登录验证

    用户在表单输入用户名与密码,通过Ajax提交给服务器,服务器验证后返回响应信息,客户端通过响应信息确定是否登录成功,成功,则跳转到首页,否则,在页面上显示相应的错误信息

    # 创建用户表,提前录入用户信息
    class User(models.Model):
        username = models.CharField(max_length=32)
        password = models.CharField(max_length=32)
    models.py
    urlpatterns = [
        url(r'^login/$', views.login),
    ]
    urls.py
    def login(request):
        if request.method == 'GET':
            return render(request, 'login.html')
        elif request.is_ajax():
            response = {'status': 100, 'msg': None}
            username = request.POST.get('username')
            password = request.POST.get('password')
            user_obj = models.User.objects.filter(username=username, password=password).first()
            if user_obj:
                # 用户名和密码都对了
                # return redirect('')  出错
                response['msg'] = '登录成功'
            else:
                response['status'] = 101
                response['msg'] = '用户名或密码错误'
    
            return JsonResponse(response)
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
        <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    </head>
    <body>
    <div class="col-md-6 col-md-offset-3">
        <div class="panel panel-primary">
            <div class="panel-heading">
                <h3 class="panel-title">网页</h3>
            </div>
            <div class="panel-body">
                <h1 class="text-center">登录</h1>
                <form action="" method="post">
                    <p>用户名:<input type="text" id="id_username" class="form-control"></p>
                    <p>密码:<input type="password" id="id_password" class="form-control"></p>
                    <input id="id_btn" type="button" value="提交" class="btn btn-primary btn-block"><span class="error"
                                                                                                        style="color: red"></span>
            </div>
        </div>
    </div>
    </body>
    <script>
        $('#id_btn').click(function () {
            $.ajax({
                url: '/login/',
                method: 'post',
                data: {username: $('#id_username').val(), password: $('#id_password').val()},
                success: function (data) {
                    // data 现在是对象类型
                    {#console.log(data)#}
                    if (data.status == 100) {
                        //登录成功,重定向到百度,前端重定向
                        location.href = '/'
    
                    } else {
                          //登录失败
                        $('.error').html(data.msg)
                    }
                },
                error: function (data) {
                    console.log(data)
                }
            })
    
        })
    </script>
    </html>
    login.html

    2 上传文件(ajax和form两种方式)

    1 http --post--请求,有编码格式,主流有三种
        urlencoded :默认的----》从request.POST取提交的数据
        form-data :上传文件的----》从request.POST取提交的数据,request.FILES中取文件
        json      :ajax发送json格式数据-----》request.POST取不出数据了
        
    2 使用ajax和form表单,默认都是urlencoded格式
    3 如果上传文件:form表单指定格式,ajax要使用Formdata对象 4 如果编码方式是urlencoded格式,放到body体中数据格式如下 username=lqz&password=123 5 如果是formdata编码格式,body体中是:两部分,数据和文件 6 如果是json格式,body体中的格式是:就是json格式字符串 -注意:注意:注意:如果这种格式,request.POST取不到值了

    form表单上传文件

    urlpatterns = [ 
        url(r'^file_upload/', views.file_upload),    
    ]
    urls.py
    def file_upload(request):
        if request.method == 'GET':
            return render(request,'file_upload.html')
        else:
            name = request.POST.get('name')
            myfile = request.FILES.get('myfile') # 拿到文件
            print(type(myfile)) # 查看类型
            with open(myfile.name, 'wb') as f:
                for line in myfile:
                    f.write(line)
    
            return HttpResponse('上传成功')
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    </head>
    <body>
    
    <h1>form表单上传文件</h1>
    <form action="" method="post" enctype="multipart/form-data">
        <p>用户名:<input type="text" name="name"></p>
        <p>文件:<input type="file" name="myfile"></p>
        <input type="submit" value="提交">
    
    </form>
    </body>
    </html>
    file_upload.html

    ajax 上传文件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    </head>
    <body>
    
    <h1>ajax上传文件</h1>
    <p>用户名:<input type="text" id="id_name"></p>
    <p>文件:<input type="file" id="id_myfile"></p>
    <button id="id_btn">提交</button>
    </body>
    
    <script>
    
        $('#id_btn').click(function () {
            //如果要上传文件,需要借助于一个js的FormData对象
    
            var formdata = new FormData() //实例化得到一个FormData对象
            formdata.append('name', $('#id_name').val()) //追加了一个name对应填入的值
            //能追加文件
            var file = $('#id_myfile')[0].files[0]
            formdata.append('myfile', file)
            $.ajax({
                url: 'file_upload',
                method: 'post',
                //上传文件,一定要注意如下两行
                processData: false,  //不预处理数据,
                contentType: false,  //不指定编码格式,使用formdata对象的默认编码就是formdata格式
                data: formdata,
                success: function (data) {
                    console.log(data)
    
                }
            })
    
        })
    </script>
    </html>
    file_upload.html

    3 ajax上传json格式

    urlpatterns = [
     
        url(r'^ajax_json/', views.ajax_json),
     
    ]
    urls.py
    def ajax_json(request):
        import json
        if request.method == 'GET':
            return render(request,'ajax_json.html')
    
        else:
            # json格式,从POST中取不出来
            name = request.POST.get('name')
            print(type(request.POST)) # 实际上不是一个真正的字典格式
            # from  django.http.request import QueryDict
            print(name)
            # 在body体中,b格式
            request.data = json.loads(request.body)
    
            name = request.data.get('name')  # 拿到用户名
            password = request.data.get('password') # 拿到密码 
            print(name)
            print(password)
            return HttpResponse('ok')
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    </head>
    <body>
    
    <h1>ajax提交json格式</h1>
    
    <p>用户名: <input type="text" id="id_name"></p>
    <p>密码: <input type="password" id="id_password"></p>
    <button id="id_button">提交</button>
    </body>
    
    <script>
    
        $('#id_button').click(function () {
    
            $.ajax({
                url: '/ajax_json/',
                method: 'post',
                contentType: 'application/json',  //json格式需指定编码格式
                  // 放json格式字符串
                data: JSON.stringify({name:$('#id_name').val(),password:$('#id_password').val()}),
                success: function (data) {
                    console.log(data)
    
                }
            })
    
        })
    </script>
    </html>
    ajax_json.html

    使用ajax上传json格式数据,写一个装饰器,实现不论前端以什么格式传递数据,我从视图函数中都从request.data中取值(POST的数据)

    urlpatterns = [
        url(r'^test_json/', views.test_json),
    
    ]
    urls.py
    from django.shortcuts import render, redirect, HttpResponse
    from django.http import JsonResponse
    
    from app01 import models
    import json
    
    
    def json_paser(func):
        def inner(request, *args, **kwargs):
            if request.method == 'POST':
                try:
                    """
                  只有post请求才有这种情况,get请求就不用管了
                  直接去loads.body,如果body里面是json格式,毫无疑问就有值了
                  能够loads到就只有一种情况就是通过json格式传过来的,其它两种
                  情况就会抛异常
                    """
                    request.data = json.loads(request.body)
                except Exception as e:
                    request.data = request.POST
    
            res = func(request, *args, **kwargs)
            return res
    
        return inner
    
    
    @json_paser
    def test_json(request):
        if request.method == 'GET':
            return render(request, 'test_json.html')
        else:
            print(request.data)
            return HttpResponse('ok')
            # return render(request,'book_page.html') # 返回的是一个纯的html页面
            # return redirect('http://www.baidu.com') # 直接报错
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
        <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    </head>
    <body>
    
    <button id="id_button">点我</button>
    </body>
    <script>
        $('#id_button').click(function () {
            $.ajax({
                url: '/test_json/',
                method: 'post',
                contentType: 'application/json',
                data: JSON.stringify({name: 'lqz', age: 18}),
                {#data:{name:'lqz',age:19},#} //urlencoded格式提交
                success: function (data) {
                    console.log(data)
    
    
                }
            })
        })
    
    </script>
    </html>
    test_json

    补充知识

    json.loads(b'dfdasfda')
    问题:json可以直接loads bytes格式吗?
      -3.5之前不可以
      -3.6以后可以

    Django内置的serializers(把对象序列化成json字符串)(了解)

    把对象转成json格式字符串,返回给前端,django内置的不好用,字段不能控制

    目前阶段,要做序列化,for循环拼列表套字典

    from django.core import serializers
    urlpatterns = [
        url(r'^test/', views.test),
    ]
    urls.py
    def test(request):
        user_list = models.User.objects.all()
        ret = serializers.serialize("json", user_list)
    
        return HttpResponse(ret)
    views.py
    class User(models.Model):
        name=models.CharField(max_length=32)
        password=models.CharField(max_length=32)
    models.py

     

    从来就没有正确的选择,我们只不过是要努力奋斗,使当初的选择变得正确。
  • 相关阅读:
    231. Power of Two
    204. Count Primes
    205. Isomorphic Strings
    203. Remove Linked List Elements
    179. Largest Number
    922. Sort Array By Parity II
    350. Intersection of Two Arrays II
    242. Valid Anagram
    164. Maximum Gap
    147. Insertion Sort List
  • 原文地址:https://www.cnblogs.com/gfeng/p/14586574.html
Copyright © 2011-2022 走看看