[Django] 使用 JSON 實現 AJAX

程式語言:Python
Package:

  • Django
  • json
GitHub ajaxExample

功能:只需更新部分網頁,無需全部重載

# view.py
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt

def ajax_jquery(request):
    is_ajax = False
    if request.is_ajax():
        is_ajax = True
    test = {'GET': 'GET',
            'array': [1, 2, 3, 4],
            'a': request.GET['a'],
            // "b": [1, 2, 3] in index.html 
            'b[]': request.GET.getlist('b[]'),
            'is_ajax': is_ajax,
            }
    return JsonResponse(test)

@csrf_exempt #忽略 csrf
def ajax_jquery_POST(request):
    is_ajax = False
    if request.is_ajax():
        is_ajax = True
    test = {'POST': 'POST',
            'is_ajax': is_ajax,
            }
    return JsonResponse(test)

兩種處理 csrf 的方法:

  • @csrf_exempt,不執行確認機制,如上
  • 在 template 加入設定如下
// index.html
<script>
    $.ajaxSetup({
        data: {
            csrfmiddlewaretoken: '{{ csrf_token }}'
        }
    });
</script>

回傳 json 的方法

# For Pre-Django 1.7
import json

from django.http import HttpResponse

response_data = {}
response_data['result'] = 'error'
response_data['message'] = 'Some error message'
return HttpResponse(json.dumps(response_data), content_type="application/json")
# For Django 1.7+
from django.http import JsonResponse
return JsonResponse({'foo':'bar'})

需要有專門處理 ajax 的網址,或是用 request.is_ajax() 區別處理
# urls.py
import ajax.views

url(r'^ajax_jquery/$', ajax.views.ajax_jquery, name='ajax-jquery')
url(r'^index/$', ajax.views.index, name='index'),

jQuery 處理 ajax 的方法

jQuery.get( url [, data ] [, success ] [, dataType ] ) 等同
$.ajax({
  url: url,
  data: data,
  success: success,
  dataType: dataType
});

list
# view.py
def ajax_list(request):
    print(request.GET.get('name')) # "z-windr"
    a = range(100)
    # safe 預設為 True => 只能傳 dictionary
    # False => 可傳 dic 以外的物件
    return JsonResponse(list(a), safe=False)
// index.html
$.get("/ajax_list/",
    {
        name: "z-windr",
        phone: "123"
    },
    function(data) {
    //返回值 data 在這裡是一個列表
    for (var i = data.length - 1; i >= 0; i--) {
        // 把 data 的每一項顯示在網頁上
        $('#result1').append(' ' + data[i]);
    }
});
// output:99 98 97 ... 0

dictionary
# view.py
def ajax_dict(request):
    is_ajax = False
    if request.is_ajax():
        is_ajax = True
    name_dict = {'twz': 'python and Django',
                 'abc': 'teach Django', 
                 'is_ajax': is_ajax}
    return JsonResponse(name_dict)
// index.html
$.get("/ajax_dict/", function(data) {
    //返回值 data 在這裡是一個字典
    for (var i in data) {
        // i 為 key,把 data 的每一項顯示在網頁上
        $('#result2').append("<br>" + i + " : " + data[i] + "<br>");
    }
});
// output
// twz : python and Django
// abc : teach Django
// is_ajax : true

jQuery.ajax( [settings ] )
參數依需求設定,只有 url 是必需
// index.html
$.ajax({
    url: "/ajax_jquery_sample/",
    data: {
        "a": "123",
        "b": [1, 2, 3]
    },
    success: function(data) {
        //返回值 data 在這裡是一個字典
        for (var i in data) {
            // 把 data 的每一項顯示在網頁上
            $('#result5').append("<br>" + i + " : " + data[i] + "<br>");
        }
    },
    // 錯誤時執行的函式
    error: function(xhr, ajaxOptions, thrownError) {
        alert(xhr.status);
        alert(thrownError);
    },
    //請求完成時執行的函式(不論結果是success或error)。
    complete: function(XMLHttpRequest, textStatus) {
        // the options for this ajax request
        alert("complete : " + textStatus);
    },
    //發送請求之前可在此修改 XMLHttpRequest 物件
    //如添加 header 等,你可以在此函式中 return flase 取消 Ajax request。
    beforeSend: function(XMLHttpRequest) {
        // the options for this ajax request
        alert("beforeSend");
    },
    type: "POST", //預設為 GET
    dataType: "json" //無指定自動選擇
});
簡單版
$.ajax({
    url: "/ajax/",
    data: {
        "a": "123",
        "b": [1, 2, 3]
    },
    success: function(data) {
        //返回值 data 在這裡是一個字典
        for (var i in data) {
            // 把 data 的每一項顯示在網頁上
            $('#result3').append("<br>" + i + " : " + data[i] + "<br>");
        }
    }
});

留言