Django:Django和Ajax

Posted neozheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django:Django和Ajax相关的知识,希望对你有一定的参考价值。

向服务器发送请求的途径:

1. 浏览器地址栏,默认get请求

2. form表单: 

  get请求;

  post请求

3. a标签,默认get请求

4. Ajax:get请求;post请求

  Ajax的特点(记住):

    (1) 异步请求

    (2)局部刷新

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

  • 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
  • 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

优点:

  • AJAX使用Javascript技术向服务器发送异步请求
  • AJAX无须刷新整个页面

 

基于Jquery的Ajax实现

目录结构:

urls.py

from django.contrib import admin
from django.urls import path

from app01 import views

urlpatterns = [
    path(\'admin/\', admin.site.urls),
    path(r"index/",views.index),
    path(r"test_ajax/",views.test_ajax) # ajax的路径需要有流程线(如,路由分发的路径,视图函数,页面等)
]

views.py

from django.shortcuts import render,HttpResponse

# Create your views here.

def index(request):

    return render(request,"index.html")

def test_ajax(request):
    return HttpResponse("hello world")

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<h2>this is Index</h2>
<button class="ajax">Ajax</button>
<p class="content"></p>
</body>
<script>
$(".ajax").click(function () {
    $.ajax({
        {# ajax请求的url;IP和端口没写就默认为当前的 #}
        url:"/test_ajax/",
        {# 请求方式;默认get #}
        type:"get",
        {#回调函数#}
        success:function (data) {
            $(".content").html(data)
        }
    })
})
{# 上述Ajax流程:点击button按钮,通过ajax向 特定的url发送请求;服务器返回字符串 "hello world"并传给回调函数的形参 data;回调函数决定怎么在页面上展示data   #}
</script>
</html>

 

Ajax传递数据:通过 data:{ } 的形式 发送数据

urls.py

from django.contrib import admin
from django.urls import path

from app01 import views

urlpatterns = [
    path(\'admin/\', admin.site.urls),
    path(r"index/",views.index),
    path(r"plus/",views.plus)
]

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>

<input type="text" class="val1">+<input type="text" class="val2">=<input type="text" class="val3"> <button class="cal">计算</button>

</body>
<script>

$(".cal").click(function () {
    $.ajax({
        url:"/plus/",
        type:"post",
        {#ajax的input中不需要添加 name 属性,只需要 class或id 能找到它就行;但form表单需要利用 name属性去取值#}
        data:{
            {# input框中的值是字符串格式 #}
            "val1":$(".val1").val(),
            "val2":$(".val2").val()
        },
        success:function (data) {
            $(".val3").val(data)
        }
    })
})


</script>
</html>

views.py

from django.shortcuts import render,HttpResponse

def plus(request):
    print(request.POST)
    val1 = request.POST.get("val1")
    val2 = request.POST.get("val2")

    val3 = int(val1) + int(val2)

    return HttpResponse(val3)

注:settings.py  MIDDLEWARE 中的  \'django.middleware.csrf.CsrfViewMiddleware\' 需要注释掉

 

基于Ajax的登陆验证(跨语言的Json)

目录结构同上;settings.py 也注释掉 csrf

urls.py

from django.contrib import admin
from django.urls import path

from app01 import views

urlpatterns = [
    path(\'admin/\', admin.site.urls),
    path(r"index/",views.index),
    
    path(r"login/",views.login)
]

views.py

from django.shortcuts import render,HttpResponse

from app01.models import User

def login(request):
    print(request.POST)
    user = request.POST.get("user")
    psw = request.POST.get("psw")

    user_obj = User.objects.filter(name=user,psw=psw).first()
    res = {"user":None,"msg":None}

    if user_obj:  # 能在数据库中匹配出来
        res["user"] = user_obj.name
    else:
        res["msg"] = "用户名密码错误"

    # 字典格式的数据类型不能直接发送,需要先转化为字符串格式
    import json
    # 利用json.dumps()序列化
    return HttpResponse(json.dumps(res))

 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>

{#form表单的action也没必要写,其实form标签也没必要;只是习惯上把form控件标签放到form中#}
<form>
    用户名 <input type="text" class="user">
    密码 <input type="password" class="psw">
    {# 用ajax发请求时 input的type用"button",不要用"submit",否则就变成了form表单发送请求 #}
    <input type="button" value="submit" class="login_btn"><span class="error"></span>
</form>

</body>
<script>

{# 登陆验证 #}
$(".login_btn").click(function () {
    {# 把ajax内置在某个事件中 #}
    $.ajax({
        url:"/login/",
        type:"post",
        data:{
            "user":$(".user").val(),
            "psw":$(".psw").val()
        },
        success:function (data) {
            console.log(data)
            {# 此时data为json字符串格式 #}
            console.log(typeof data)

            {# 此时data这个字符串交给JS去处理了;就需要用JS的反序列化方法 #}
            {# 只要该语言支持json接口,它就能反解成自己支持的数据类型:python的字典会反解成JS的对象({}),python的列表会反解成JS的数组([])#}
            {# JSON.parse()是JS的反序列化方法 #}
            var new_data = JSON.parse(data)
            console.log(new_data)
            console.log(typeof new_data)

            if (new_data.user){
                {# location.href= 表示前端跳转 #}
                location.href="https://www.baidu.com"
            }else {
                $(".error").html(new_data.msg).css({"color":"red","margin-left":"10px"})
            }

        }
    })
})


</script>
</html>

 

文件上传:

请求头ContentType:

ContentType指的是消息主体的编码类型,常见的类型共有3种:

   1. application/x-www-form-urlencoded:这应该是最常见的 POST 提交数据的方式了。浏览器的原生 <form> 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。请求类似于下面这样

POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8

user=yuan&age=22

 

  2. multipart/form-datamultipart/form-data:这又是一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 <form> 表单的 enctype 等于 multipart/form-data

  3. application/json:Json格式的字符串作为请求头

 

基于form表单的文件上传

urls.py

from django.contrib import admin
from django.urls import path

from app01 import views

urlpatterns = [
    path(r"file_put/",views.file_put)
]

views.py

from django.shortcuts import render,HttpResponse

def file_put(request):
    if request.method == "POST":


        # 1. 基于form表单的文件上传
        print(request.POST)
        # request.POST 只有在 contentType = urlencoded 时候才有数据

        # 注意:上传成功的文件放在 request.FILEs 这个属性里面
        print(request.FILES)

        # 下载所上传的文件
        file_obj = request.FILES.get("avatar")
        # 文件对象有一个属性 .name 表示文件名
        with open(file_obj.name,"wb") as f:
            for line in file_obj:
                f.write(line)
        
        return HttpResponse("ok")

    return render(request,"file_put.html")

file_put.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

</head>
<body>
<h3>基于form表单的文件上传</h3>

{# 注意:上传文件的form表单中要写上 enctype="multipart/form-data" #}
<form action="" method="post" enctype="multipart/form-data">
    用户名 <input type="text" name="user">
    {# 上传文件 input的type属性值是 "file" #}
    头像 <input type="file" name="avatar">
    <input type="submit">

</script>
</html>

 

利用Ajax上传普通数据

views.py

from django.shortcuts import render,HttpResponse

def file_put(request):
    if request.method == "POST":
        
        return HttpResponse("ok")

    return render(request,"file_put.html")

file_put.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

</head>
<body>


<h3>基于Ajax的文件上传</h3>

{# 利用Ajax上传普通数据  #}
<form action="" method="post">
    用户名 <input type="text" name="user">
    <input type="button" class="btn" value="Ajax">
</form>

</body>
<script>
    {#利用Ajax上传普通数据  #}
    $(".btn").click(function () {
        $.ajax({
            {#url不写默认为当前路径#}
            url: "",
            type: "post",
            {#不指定enctype,默认用application/x-www-form-urlencoded #}
            data: {
                a: 1,
                b: 2
            },
            success: function (data) {
                console.log(data)
            }
        })
    })
 {#不论是form表单还是Ajax都有一个默认的请求头 application/x-www-form-urlencoded  #}

</script>
</html>

 

Ajax传递Json数据

views.py

from django.shortcuts import render,HttpResponse

def file_put(request):
    if request.method == "POST":
         # 3. Ajax传递Json数据
        print("request.body",request.body)   # request.body:请求报文中的请求体(请求体的源数据);
        # request.body b\'{"a":1,"b":2}\'   # 此数据可通过python的json.dumps()方法获取
        print("request.POST",request.POST)  # 此时 request.POST 中没有数据
        # request.POST <QueryDict: {}>
    
         return HttpResponse("ok")

    return render(request,"file_put.html")

file_put.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

</head>
<body>
{#Ajax传递Json数据#}
<form action="" method="post">
    用户名 <input type="text" name="user">
    <input type="button" class="btn" value="Ajax">
</form>
</body>
<script>

{#Ajax传递Json数据#}
$(".btn").click(function () {
        $.ajax({
            {#url不写默认为当前路径#}
            url:"",
            type:"post",
            {#告诉服务器编码类型为json数据#}
            contentType:"application/json",
             {#然后需要用JS的方法把数据变成Json数据类型:JSON.stringify():序列化 #}
             {#然后请求体中的数据就是 {"a":"1","b":"2"} 类型的json字符串 #}
            data:JSON.stringify({
                a:1,
                b:2
            }),
            success:function (data) {
                console.log(data)
            }
        })
    })

</script>
</html>

 

基于Ajax的文件上传

views.py

from django.shortcuts import render,HttpResponse

def file_put(request):
    if request.method == "POST":
        # 4. 基于Ajax的文件上传
        print("request.body", request.body)
        print("request.POST", request.POST)  # request.POST <QueryDict: {\'user\': [\'neo\']}>
        print(request.FILES)  # <MultiValueDict: {\'avatar\': [<InMemoryUploadedFile: default.jpg (image/jpeg)>]}>


        # 下载所上传的文件
        file_obj = request.FILES.get("avatar")
        # file_obj = request.FILES.get("avatar")
        # 文件对象有一个属性 .name 表示文件名
        with open(file_obj.name,"wb") as f:
            for line in file_obj:
                f.write(line)

        return HttpResponse("ok")

    return render(request,"file_put.html")

 

file_put.html