Http302使用Ajax发布到Django视图时的响应

时间:2015-08-22 01:00:42

标签: jquery python ajax django

我正在尝试构建一个使用ajax获取输入的Web应用程序。输入在服务器端发送到Django,我很难获得正确重定向的URL。我知道目前的问题与django翻译应用程序有关。

以下是相关部分。

的Ajax

 $(document).ready(function(){
  $('#applicant_form').on('submit', function(event){
    event.preventDefault() //this will stop the file from submitting the form manually.
    $.ajax({
        url :'/save_applicant/', // the endpoint
        type : "POST", // http method
        data : { the_post : "Yay" }, // data sent with the post request
        dataType: "json",
        // handle a successful response
        success : function(json) {
            console.log("success"); // another sanity check
        },

        // handle a non-successful response
        error : function(xhr,errmsg,err) {
            $('#results').html("<div class='alert-box alert radius' data-alert>Oops! We have encountered an error: "+errmsg+
                " <a href='#' class='close'>&times;</a></div>"); // add the error to the dom
            console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
        }
    });
  });
});

HTML / DJANGO TEMPLATES

<form method = "POST" action = "" class="form bgform" id="applicant_form">
    {% csrf_token %}
    {{ applicant_form|crispy }}
    <input class="btn btn-default" type="submit" name="Save" />
</form>

views.py

def save_applicant(request):
if request.method =='POST':
    id = None
    if 'applicant' in request.session:
        id = request.session['applicant']

    applicant_form = ApplicantForm(request.POST)
    if applicant_form.is_valid():
        session_applicant  = applicant_form.save(commit=False)
        if id:
            session_applicant.id = id
        else:
            session_applicant.save()
            request.session['applicant'] = session_applicant.id 
        return HttpResponse(json.dumps({'status':'applicant_saved'}), content_type='application/json')

    else:
        return HttpResponse(applicant_form.errors.as_json(),content_type='application/json')

else:
    return HttpResponse(json.dumps({'status':'not_post'}),content_type='application/json')

urls.py

from django.conf.urls import include, url
from django.contrib import admin
from django.conf.urls.i18n import i18n_patterns

urlpatterns = [
]
urlpatterns += i18n_patterns(
    url(r'^$', 'plan_b_profile.views.home', name='home'),
    url(r'^save_applicant/','plan_b_profile.views.save_applicant',name='save_applicant'),
    url(r'^admin/', include(admin.site.urls)),
)

命令行

[21/Aug/2015 20:53:43]"POST /save_applicant HTTP/1.1" 302 0
[21/Aug/2015 20:53:43]"GET /en/save_applicant/ HTTP/1.1" 200 22 <---- HOW TO FIX THIS

再次感谢!

4 个答案:

答案 0 :(得分:4)

我认为此问题的最佳解决方案是在JavaScript中动态分配帖子网址。

重写您的模板,这样您就可以将您的网址存储在由django反转的网址中,例如以action格式存储:

<form method = "POST" action="{% url "save_applicant" %}" class="form bgform" id="applicant_form">
    {% csrf_token %}
    {{ applicant_form|crispy }}
    <input class="btn btn-default" type="submit" name="Save" />
</form>

将AJAX发布到该URL而不是静态URL,它将已经带有语言前缀,因此重定向不会发生:

$(document).ready(function(){
  $('#applicant_form').on('submit', function(event){
    event.preventDefault() //this will stop the file from submitting the form manually.
    $.ajax({
        url :$(this).attr('action'), // the endpoint
        type : "POST", // http method
        data : { the_post : "Yay" }, // data sent with the post request
        dataType: "json",
        // handle a successful response
        success : function(json) {
            console.log("success"); // another sanity check
        },

        // handle a non-successful response
        error : function(xhr,errmsg,err) {
            $('#results').html("<div class='alert-box alert radius' data-alert>Oops! We have encountered an error: "+errmsg+
                " <a href='#' class='close'>&times;</a></div>"); // add the error to the dom
            console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
        }
    });
  });
});

答案 1 :(得分:1)

所以我放弃了这个问题,实现了我的愚蠢错误。我刚刚将urls.py更改为以下内容:

var urls = ["http://api.example.com/items?key=123456789"
           , " http://api.example.com/?key=123456789"];

function foodQuery(url) {

    var foodURL = url;
    return $.ajax(settings);

}

$.when.apply($, $.map(urls, function(url, index) {
  return foodQuery(url)
}));

答案 2 :(得分:1)

即使使用自己的解决方案,如果在使用i18n语言扩展时从视图中返回404 Not Found状态,您仍可能会发现收到302重定向。当一些请求参数不正确时,我这样做(我使用相同的HTTP GET和HTTP / AJAX POST视图)。

原因是一些Django中间件(我认为LocaleMiddleware)会在中间件堆栈的上行处理响应,看到找不到页面,并返回带有浏览器语言前缀的302重定向相反。然后,当在下一个请求中找不到(在这种情况下)时,您将获得不同的404 Not Found响应。这很糟糕,因为你永远无法看到原始请求失败的原因。

在您的情况下,您可以通过执行以下操作来解决此问题:

...
urlpatterns = [
    url(r'^en/save_applicant/','plan_b_profile.views.save_applicant',name='save_applicant'),
]
...

这让有问题的中间件误认为它已经是一个特定于语言的页面(实际上它就是你在按钮和ajax中返回英文的原因)。

您还可以使用solid-i18n-url等解决方案完全删除重定向。

编辑:然而,经过反思,首先返回这样的404可能是一个坏主意; 400 Bad Request会更好..

答案 3 :(得分:0)

对于它的价值,我在Django的HTTP 302响应中遇到了同样的问题。如果URL中没有结尾斜杠,Django将返回HTTP 302(我确实在模板代码中看到一个斜杠,但Django日志讲述了一个不同的故事):

Web Deploy 3.0

确保在URL末尾使用斜杠(即/ save_applicant ** / **)应该可以使其正常工作。

@GwynBleidD的答案,建议使用内置的{%url%}模板。