django中的ajax組件

django中的ajax

Ajax(Asynchronous Javascript And XML)翻譯成英文就是「異步Javascript和XML」。即用Javascript語言與服務器進行異步交互,傳輸的數據爲XML,(如今使用更多的是json數據)。html

向服務器發送請求的途徑

  1. 瀏覽器地址欄 http://www.baidu.com 默認是get請求
  2. form表單發送請求:
    GET請求
    POST請求
  3. a標籤 href屬性 默認是get請求
  4. ajax()

Ajax的特色

異步交互:客戶端發送一個請求後,無需等待服務器響應結束,就能夠發送第二個請求;jquery

局部刷新:瀏覽器頁面局部刷新ajax

局部刷新的意思就是當我們在博客園註冊一個新的博客的時候,當我們輸入用戶名後鼠標移開的時候,就發送了一個請求,去驗證這個用戶是否存在,若是存在,則通知用戶該用戶名已經被註冊了。django

基於jquery實現的ajax請求

讓咱們使用pycharm從新建立一個項目,項目名爲Ajax_demo,應用名爲app01。json

# url控制器

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', views.index),
    path('test_ajax/', views.test_ajax),
]

那麼當咱們須要有對應的視圖函數 index和test_ajax:瀏覽器

# app01-->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!')

在這裏匹配了相應的視圖而後返回了一個html頁面:服務器

# index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
</head>
<body>
    <h3>功能1:發送ajax請求</h3>
    <p class="content"></p> //這裏的內容是空的
    <button class="btn">ajax</button>

    <script>
        $('.btn').click(function(){
            $.ajax({
                url:'/test_ajax/',
                type:'get',
                success:function(data){
                    $('.content').html(data)
                }
            })
        })
    </script>
</body>
</html>

這句話的意思是,當我們點擊button按鈕的時候,觸發了點擊動做,而後發送了一個ajax請求,讓咱們先看看此時是什麼樣子的:app

當咱們點擊了按鈕的時候,就發送了一個ajax請求:異步

此時一個簡單的ajax請求就發送完成了。

利用ajax實現計算器

首先我們的index.html中進行佈局:

# index.html

<h3>功能2:利用ajax實現的計算器</h3>
    <input type="text" class="num1">+<input type="text" class="num2">=<input type="text" id="sum"><button class="cal">計算</button>


        $('.cal').click(function(){
            $.ajax({
                url:'/cal/',
                type:'post',
                data:{
                    'n1':$('.num1').val(),
                    'n2':$('.num2').val(),
                },
                success:function(data){
                    console.log(data);
                    $('#sum').val(data);
                }
            })
        })

而後我們拿到了n1和n2的值,經過請求url發送給相應的視圖而後進行數據處理,最後拿到結果再返回給這個ajax。

# views.py

def cal(request):
    print(request.POST)
    n1 = int(request.POST.get('n1'))
    n2 = int(request.POST.get('n2'))
    sum = n1+n2
    return HttpResponse(sum)

此時的url控制器須要新添加一條:

path('cal/', views.cal),

其次是配置文件settings中的這一行須要註釋掉:

# 'django.middleware.csrf.CsrfViewMiddleware',

此時再查看結果:

利用ajax實現登錄認證

首先我們要開一個路由,當用戶在瀏覽器輸入http://127.0.0.1/login_btn/的時候,就匹配導對應的視圖,因此:

# url控制器

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', views.index),
    path('test_ajax/', views.test_ajax),
    path('cal/', views.cal),
    path('login/', views.login),
    path('login_btn/', views.login_btn),
]
# login_btn函數

def login_btn(request):
    return render(request, 'login_btn.html')

而後返回了這個html頁面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
</head>
<body>
    <h3>利用ajax實現登錄認證</h3>
    <form action="">
        用戶名 <input type="text" class="user">
        密碼 <input type="password" class="pwd">
        <input type="button" value="submit" class="login_btn">
        <span class="error"></span>
    </form>

    <script>
        $('.login_btn').click(function(){
            $.ajax({
                url:'/login/',
                type:'post',
                data:{
                    'user':$('.user').val(),
                    'pwd':$('.pwd').val(),
                },
                success:function(data){
                    //此時須要進行轉換
                    console.log(typeof(data));
                    var data = JSON.parse(data)
                    console.log(typeof(data));
                    if (data.user){
                        location.href = 'http://www.baidu.com'
                    }else{
                        $('.error').html(data.msg).css({'color':'red'})
                    }
                }

            })
        })
    </script>
</body>
</html>

最後ajax將請求提交到了/login/中,而後進行匹配視圖,而後就開始執行對應代碼:

def login(request):
    # print(request.POST)

    user = request.POST.get('user')
    pwd = request.POST.get('pwd')

    from .models import User
    user = User.objects.filter(user=user, pwd=pwd).first()

    ret = {
        'user': None,
        'msg': None
    }
    if user:
        ret['user'] = user.user
    else:
        ret['msg'] = 'username or password is wrong!'

    import json
    return HttpResponse(json.dumps(ret))

首先打開瀏覽器,輸入錯誤的用戶名和密碼:

而後開始輸入正確的用戶名和密碼,就會直接跳轉到百度的首頁了。

利用form表單進行文件上傳

# urls.py

path('file_put/', views.file_put),
# views.py

# 文件的上傳
def file_put(request):
    if request.method == 'POST':
        print(request.POST)

    return render(request, 'file_put.html')
# file_put.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上傳</title>
</head>
<body>
    <h3>基於form表單實現的文件上傳</h3>
    <form action="" method="post" enctype="multipart/form-data">
        用戶名 <input type="text" name="user">
        頭像 <input type="file" name="avatar">
        <input type="submit">
    </form>
</body>
</html>

此時我們輸入完用戶名和選中完圖片後,點擊提交我們查看下打印的信息。

那麼是咱們的圖片沒有上傳過來嗎?固然不是的,是由於上傳的圖片就不在這裏面。讓咱們在views.py中執行這個代碼:

print(request.FILES)

看到的是這個樣子:

那麼此時咱們就能夠肯定,這個文件是上傳過來了,存放在request.FILES中,那麼我們使用request.FILES.get就能夠把這個圖片對象拿到了。

# views.py
 
 def file_put(request):
    if request.method == 'POST':
        print(request.POST)  #
        # print(request.body)
        print(request.FILES)  # 圖片信息

        # 將文件給取出來
        img_obj = request.FILES.get('avatar')
        with open(img_obj.name, 'wb') as f:
            for line in img_obj:
                f.write(line)
        return HttpResponse('ok!')

    return render(request, 'file_put.html')

那麼此時直接上傳的話,那麼就會在當前項目下展現這張照片。

利用ajax實現文件上傳

首先咱們須要新開一個url或者將以前的註釋掉:

# urls.py

path('file_put/', views.file_put),

ajax提交文件的方式一樣使用form表單,可是不須要給input設置name屬性,只須要設置class或者id就能夠了:

# file_put.html

    <form action="" method="post">
        用戶名 <input type="text" id="user">
        頭像 <input type="file" id="avatar" >
        <input type="button" class="btn" value="ajax">
    </form>

那麼我們須要給btn設置點擊click動做:

$('.btn').click(function(){
    
        //涉及到文件上傳 須要建立formdata對象
        var formdata = new FormData();
        formdata.append('user',$('#user').val());
        formdata.append('avatar',$('#avatar')[0].files[0]);

        $.ajax({
            url:'',
            type:'post',
            contentType:false, // 交給FormData處理編碼
            processData:false, //對數據是否進行預處理 若是不作預處理的話 就不作任何編碼了
            data:formdata,
            success:function(data){
                console.log(data)
            }
        })
    })

最後在試圖函數中進行文件保存操做:

def file_put(request):

    if request.method == "POST":
        print("body", request.body)  # 請求報文中的請求體 json
        print("POST", request.POST)  # if contentType==urlencoded ,request.POST纔有數據

        print('FILES', request.FILES)
        file_obj=request.FILES.get("avatar")
        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")

Content-Type

在我們剛剛的form表單的文件上傳和ajax文件上傳的時候,都涉及到一個請求頭的東西,這個東西是什麼呢?這個東西決定着服務器會按照哪一種編碼格式給你解碼,當你默認不寫的時候,此時的請求頭是:application/x-www-form-urlencoded,當你想發送文件類的東西,此時的請求頭應該是:form-data......

當服務器收到客戶端發送過來的請求時,首先就會去查看請求頭,判斷你的請求頭是什麼,而後進行解碼。

讓咱們分別看下這幾個請求頭:

x-www-form-urlencoded

application/x-www-form-urlencoded:表單數據編碼爲鍵值對,&分隔,能夠當成我們的GET請求中?後面的數據,讓咱們發送一個庶幾乎看看:
<form action="" method="post"> 用戶名 <input type="text" name="user"> 密碼 <input type="password" name="pwd"> <input type="submit" value="submit"> </form>

那麼咱們須要一個視圖函數還進行處理:

def file_put(request):

    if request.method == "POST":
        print("body", request.body)  # 請求報文中的請求體 json
        print("POST", request.POST)  # if contentType==urlencoded ,request.POST纔有數據

        return HttpResponse("OK")

    return render(request, "file_put.html")

當咱們在瀏覽器輸入admin和123的時候,讓咱們來看下打印的結果是什麼:

咱們剛剛說過,當咱們請求頭什麼都不寫的話,那麼就是默認的x-www-form-urlencoded,當請求頭是這種的話,此時咱們打印request.POST是有值的,也就這一種請求方式request.POST纔有值。

讓咱們如今發送一個json的數據

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
</head>
<body>
<form action="" method="post">
    用戶名 <input type="text" class="user">
    密碼 <input type="password" class="pwd">
    <input type="button" value="submit" class="btn">
</form>

<script>
    $('.btn').click(function(){
        $.ajax({
            url:'',
            type:'post',
            data:JSON.stringify({
                a:1,
                b:2
            }),
            success:function(data){
                console.log(data)
            }

        })
    })
</script>
</body>
</html>

視圖函數中是這樣的:

def send_json(request):
    if request.method == 'POST':
        print('body', request.body)
        print('post', request.POST)
        print('files', request.FILES)
        return HttpResponse('ok!')
    return render(request, 'send_json.html')

當咱們發送數據的時候,經過解碼收到的就是這樣的數據:

就和咱們剛剛說的同樣,當請求頭是x-www-form-urlencoded的時候,request.POST纔會有數據,其餘的就沒有。

相關文章
相關標籤/搜索