[Django之框架設計模型(MTV與MVC)、Ajax]

tankII發表於2021-09-09

框架設計模型(MTV與MVC)

MTV
	M:models模型層
    T:templates模板層
	V:views檢視層
MVC
	M:models模型層
     V:views檢視層
     C:controller控制層
django框架自稱是MTV 其實本質也是MVC

Ajax

Django與ajax(入門)

AJAX(Asynchronous Javascript And XML)翻譯成中文就是“非同步JavaScript和XML”。是指一種建立互動式,快速動態網頁應用的網頁開發技術,無需重新載入整個網頁的情況下,能夠更新部分網頁的技術。

透過在後臺與伺服器進行少量資料交換,AJAX可以使網頁實現非同步更新,這意味著在不重新載入整個網頁頁面的情況下,對網頁的部分內容進行更新

AJAX是一種用於快速動態網頁的技術

傳統的網頁(不使用AJAX)如果需要更新內容,必須重新載入整個頁面,而前面談到AJAX是什麼,其主要就是非同步提交,那我們來聊聊同步和非同步提交的區別

同步提交:當使用者傳送請求時,當前頁面不可以使用,伺服器響應頁面到客戶端,響應完成,客戶才可以使用網頁

非同步提交:當使用者傳送請求時,當前頁面可以繼續使用,當非同步請求的資料響應給頁面,頁面把資料顯示出來

AJAX的工作原理:

相當於在使用者和伺服器之間加了一箇中間層(AJAX引擎),使使用者操作與伺服器響應非同步化。並不是所有的使用者請求都提交給伺服器,像一些資料驗證和資料處理等都交給ajax引擎自己來做,只有確定需要從伺服器讀取資料時再由AJAX引擎代為向伺服器提交請求

客戶端傳送請求,請求交給xhr,xhr把請求提交給服務,伺服器進行業務處理,伺服器響應資料交給xhr物件,xhr物件接收資料,由javascript把資料寫到頁面上,如下圖所示:

圖片描述

Ajax基本語法:

$.ajax({
            url:'',  // 控制提交地址    規律與form標籤的action引數一致
            type:'post',  // 控制請求方式
            data:{'i1':i1Val,'i2':i2Val},  // 傳送的資料
    	    dataType:JSON,   //自動反序列化
            success:function (args) {
                    // 非同步回撥函式
                    {#alert(args)#}
                    // 檢視input框並且寫入資料
                    $('#i3').val(args)
            }
        })

寫ajax跟後端互動

1 使用原生js寫ajax請求(沒有人用)
     第一:麻煩
     第二:區分瀏覽器,需要做瀏覽器相容
2 現在主流做法(現成有人封裝好了,jquery,axios..)
    以jquery為例

透過Ajax,實現前端輸入兩個數字,伺服器做加法,返回到前端頁面

​ 檢視函式views.py

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)

路由urls.py

urlpatterns = [
     url(r'^ajax_test/',views.ajax_test),
    url(r'^sum/',views.sum),
]

ajax_test.html

!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>

注意:

1 大坑
    如果在form表單中,寫button和input是submit型別,會觸發form表單的提交
    如果不想觸發:
        不寫在form表單中
        使用input,型別是button
        
2 坑
    後端響應格式如果是:html/text格式,ajax接收到資料後需要自己轉成物件
    後端響應格式是:json,ajax接收到資料後會自動轉成物件
    總結:後端返回資料,統一都用JsonResponse、
    
3 坑
    如果使用了ajax,後端就不要返回rediret,render,HttpResponse
    直接返回JsonResponse

上傳檔案(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傳輸過來的資料,如果是預設的urlencoded編碼格式,那麼只要滿足此格式,都會封裝到POST中!
    form傳輸過來的資料,如果改成了form-data的編碼格式,那麼滿足此格式的(也就是檔案)放在FILES中,其他滿足urlencoded編碼格式的放在POST,都不滿足的放在body中!!!

form表單上傳檔案

urlpatterns = [ 
    url(r'^file_upload/', views.file_upload),    
]

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('上傳成功')

!DOCTYPE html>
html lang="en">
head>
    meta charset="UTF-8">
    title>Title/title>
    script src="">/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>

ajax 上傳檔案

!DOCTYPE html>
html lang="en">
head>
    meta charset="UTF-8">
    title>Title/title>
    script src="">/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>

			# ajax傳送檔案資料
        	$('#d1').on('click',function () {
                // 1.先生成一個內建物件
                let formDataObj = new FormData();
                
                // 2.新增符合urlencoded格式的普通鍵值對資料
                formDataObj.append('name','jason');
                formDataObj.append('password',123);
                
                // 3.新增檔案資料
                formDataObj.append('myfile',$('#myfile')[0].files[0]);
                
                // ajax傳送給後端
                $.ajax({
                    url:'',  // 控制提交地址    規律與form標籤的action引數一致
                    type:'post',  // 控制請求方式
                    data:formDataObj,  // 傳送的資料

                    // 額外指定兩個引數
                    contentType:false,  // 不採用任何編碼 後端能夠直接識別formdata物件
                    processData:false,  // 不處理formdata物件 直接傳送即可

                    success:function (args) {
                    }
                })
            });
/script>
/html>

ajax上傳json格式

url.py

# url.py

urlpatterns = [
 
    url(r'^ajax_json/', views.ajax_json),
 
]

views.py

# views.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')

ajax_json.html

# ajax_json.html

!DOCTYPE html>
html lang="en">
head>
    meta charset="UTF-8">
    title>Title/title>
    script src="">/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/',  # 和from表單中的 action一毛一樣
            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>

form表單預設是urlencoded編碼格式

資料格式username=jason&password=234
django後端針對符合urlencoded格式的資料會自動解析並封裝到request.POST中
django後端針對form-data格式的資料檔案自動封裝到request.FILES中 普通的符合urlencoded還是封裝到request.POST中

# ajax預設是urlencoded編碼格式
	1.ajax傳送json格式資料
    	django後端不做任何處理 直接以二進位制形式存放在request.body中
        data
        contentType

django內建序列化模組

Django內建的serializers(把物件序列化成json字串)

把物件轉成json格式字串,返回給前端,django內建的不好用,欄位不能控制

目前階段,要做序列化,for迴圈拼列表套字典

from django.core import serializers

urlpatterns = [
    url(r'^test/', views.test),
]

def test(request):
    user_list = models.User.objects.all()
    ret = serializers.serialize("json", user_list)

    return HttpResponse(ret)

class User(models.Model):
    name=models.CharField(max_length=32)
    password=models.CharField(max_length=32)

基於ajax實現二次確認

script>
        $('.del_link').on('click',function (a) {
            var $aEle = $(this);
            var deleteId = $(this).attr('delete_id');
            // 提示二次確認
            res = confirm('你確定真的要刪嗎?');
            // 判斷是否刪除
            if (res){
                // 傳送ajax請求
                $.ajax({
                    url:"/book_delete/" + deleteId,
                    type:'get',
                    data:{},
                    success:function (args) {
                        // 1.頁面重新整理  不推薦使用
                        window.location.reload();
                        // 2.DOM操作   正規 使用者體驗好
                        $aEle.parent().parent().remove()
                    }
                })
            }else{
                alert('慫逼不敢刪啦')
            }
        })
/script>

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1795/viewspace-2797145/,如需轉載,請註明出處,否則將追究法律責任。

相關文章