【问题标题】:Ajax request not returning an HttpResponseAjax 请求不返回 HttpResponse
【发布时间】:2018-10-06 20:41:22
【问题描述】:

我正在编写一个只有一页的 django 网络应用程序。此页面包含一个带有一些输入的表单。当我单击提交按钮时,我对 python 中的函数进行了 ajax 调用。我想从这个函数中取回一些数据。

HTML 文件:

<form id="strategy" method="post" class="edit_user">
  {% csrf_token %}
  <div class="sel-schedule">
    <label>Label: </label>
    <input id="start_time" type="time" name="start_time" value="09:30" required>
  </div>
  <button type="submit" class="inactive boton-lanzar">Launch</button>
</form>

JS 文件

$('#strategy').on('submit', function(event){
    var start_time = document.getElementsByName("start_time")[0].value;
    var url = '/method_calculation/';
    $.ajax(url, {
        data: {
            'start_time': start_time,
        },
        dataType: 'json',
        success: function (data) {
          console.log("new")
        }
    })
});

网址文件:

urlpatterns = [
path('admin/', admin.site.urls),
path('', home, name='home'),
path('method_calculation/', method_calculation, name="method_calculation"),
]

查看文件:

def home(request):
    if request.method == "GET":
        return render(request, 'index.html')
    else:
        return HttpResponse("OK")


def method_calculation(request):
    if request.method == 'POST':

        start_time_hour = int(request.POST.get('start_time')[0:2])
        start_time_minute = int(request.POST.get('start_time')[3:5])
        data_comparison = caculate_summit(start_time_hour, start_time_minute)

        args = {data_comparison}
        return JsonResponse(args)

我有点困惑。

首先,我不希望页面重新加载,但如果我取出返回的 HttpResponse,它会说它需要它。

其次,使用当前文件我收到以下错误:

The view myapp.views.method_calculation didn't return an HttpResponse object. It returned None instead.

我错过了什么?

非常感谢

【问题讨论】:

  • 您正在发出GET 请求,因此该方法返回None,因此出现错误。

标签: javascript python ajax django


【解决方案1】:

当我在我的 Django 项目中使用 Ajax 进行发布请求时,我正在执行以下操作。 根据 django 文档(https://docs.djangoproject.com/en/2.1/ref/csrf/),获取 csrf 令牌的最佳方法是使用此函数:

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

然后我用这个构建了一个 ajax post 函数:

function postAjaxJson(url, data, is_csrf, callback) {
    if (is_csrf) {
        var csrftoken = getCookie('csrftoken');
        $.ajaxSetup({
            beforeSend: function(xhr, settings) {
                if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                    xhr.setRequestHeader("X-CSRFToken", csrftoken);
                }
            }
        });
    }
    $.ajax({
        url: url,
        type: "POST",
        contentType: "application/json",
        data: JSON.stringify(data),
        success: function(response) {
            callback(response);
        },
        error: function () {
            console.error("Erreur réseau avec l'url" + url);
        }
    })
}

我通常以 JSON 格式发送数据。 而且,在您看来,您会在 request.body 中找到来自 ajax 帖子的数据,而不是在 request.POST 中:

import json
def method_calculation(request):
    if request.body:

        ...
        # if json data = json.loads(request.body)
        ...
        return JsonResponse(args)

希望这能帮助您解决问题!

【讨论】:

    【解决方案2】:

    您的 AJAX 调用正在发出 GET 请求,而视图函数无法处理这种情况。结果它返回None,因此返回错误。

    因此您需要在$.ajax 调用中指定请求类型:

    $.ajax(url, {
        type: "POST",
        data: {
            start_time: start_time,
            csrfmiddlewaretoken: '{{ csrf_token }}'
        },
        dataType: 'json',
        success: function (data) {
          console.log("new")
        }
    })

    根据您的评论,您还需要指定 CSRF 令牌(鉴于 JavaScript 是使用模板呈现的,以上应该可以工作)。

    【讨论】:

    • 谢谢你的回答,我改了,现在收到403错误,我会在开新帖前找找。
    • @AlbertoCarmona:您的视图是否执行身份验证?还是 CSRF 令牌?
    • 是一个 CSRF 令牌
    猜你喜欢
    • 2013-04-23
    • 2011-10-19
    • 2016-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    • 1970-01-01
    相关资源
    最近更新 更多