Django/Javascript能处理对HTTP POST请求的条件“Ajax”响应吗?

0 投票
3 回答
1000 浏览
提问于 2025-04-15 14:45

我该如何设计一个Django/Javascript应用,让它能根据条件给普通的HTTP请求返回不同的Ajax响应呢?

在服务器上,我有一个自己做的表单对象。当浏览器提交表单数据时,服务器会检查这些数据是否符合已有的数据和规则(比如,如果这个表单是要往数据库里添加一个新实体,那么这个实体在数据库里已经存在吗?)。如果数据通过了检查,服务器就会保存数据,生成一个ID号,并把这个ID号加到表单数据里,然后把表单和数据返回给浏览器。

if request.method == 'POST':
    formClass = form_code.getCustomForm()
    thisForm = formClass(data=request.POST)
    if thisForm.isvalid():
        saveCheck = thisForm.saveData()
        t = loader.get_template("CustomerForm.html")
        c = Context({ 'expectedFormObj': thisForm })

(注意,我自定义的逻辑检查是在saveData()函数里,和isvalid()进行的HTML验证是分开的。)

到目前为止,这都是标准的Django做法(我希望如此)。但是如果数据没有通过检查,我想给浏览器发送一条消息。我想saveData()可以把消息放在表单的一个属性里,然后模板可以检查这个属性,把数据嵌入成一个javascript变量,并包含一个javascript函数来显示这个消息。不过,返回整个表单的HTML,只是为了加一条消息,感觉不太优雅(标准的Django表单提交过程也是这样,不过没关系)。在这种情况下,我想直接返回这条消息。

现在我想我可以把一个Javascript函数绑定到HTML表单的onsubmit事件上,让它发出一个XMLHttpRequest,然后服务器根据saveData()的输出来回应。不过这样的话,浏览器就会有两个请求在等待服务器的响应(一个是POST请求,一个是XHR请求)。也许成功的saveData()会重写整个页面,消除任何潜在的冲突。但我还得让服务器按照顺序先回应POST请求,再回应XHR请求,并且想办法把saveData的结果传递给XHR的响应。我想这也是可以做到的,即使没有我不知道的线程编程,但感觉会很麻烦。

我在想,或许我可以用javascript让浏览器的响应根据POST请求的响应内容来决定(要么重写整个页面,要么只显示一条消息)。但我怀疑在POST请求时,页面的javascript会把控制权交给浏览器,而任何对POST的响应都会直接重写页面。

所以,我能否设计一个流程,只有在服务器端的saveData()成功时才返回整个表单,而如果saveData()不成功,则返回一条消息,并且不重写整个表单?如果可以的话,应该怎么做呢?

3 个回答

0

顺便说一下,这不是一个答案……但可能会帮助你换个角度思考这个问题。

我遇到的问题是……Google App Engine + jQuery Ajax = 405 方法不允许

简单来说,我按照提供的代码让它工作了,但就是无法发出AJAX请求 :(。

3

在处理AJAX的时候,我用的是这个:

from django.utils import simplejson
...
status = simplejson.dumps({'status': "success"})
return HttpResponse(status, mimetype="application/json")

然后,AJAX(jQuery)可以根据返回的'status'值来做它想做的事情。

我不太确定你对表单有什么具体的需求。如果你想要一个更简单、更好的表单体验,我建议你看看 uni-formPinax 在他们的投票应用中对这个做得很好。

3

虽然你可以让你的视图去检查请求的数据,以决定响应是AJAX风格的还是普通的HTML,但我并不推荐这样做。最好把AJAX请求处理放在一个单独的URL结构里,比如说你所有的普通HTML视图的URL像是/foo/bar,而对应的API调用则是/ajax/foo/bar。

因为大多数视图会检查请求的数据,然后进行一些处理,最后创建一个Python字典并把它传递给模板引擎,所以你可以把这些共同的部分提取出来,让这个过程变得简单一些。前面几个步骤可以是一个通用的函数,只需返回Python字典,然后实际的响应可以通过将处理函数包装在模板渲染器或JSON编码器中来组成。

我通常的工作流程是先假设客户端没有JavaScript(这仍然是一个有效的假设;很多手机浏览器是没有JS的),然后实现应用程序作为静态的GETPOST处理程序。从这里开始,我会寻找我的应用程序可以通过一些客户端脚本受益的地方。例如,我通常会重新设计表单,使其通过AJAX类型的调用提交,而不需要重新加载页面。这些请求不会发送到与普通HTML表单版本相同的URL/Django视图,因为响应需要是一个简单的成功消息,格式可以是普通文本或HTML片段。

同样,从服务器获取数据的方式也会重新设计,以便返回一个简洁的JSON文档,供客户端处理到页面中。这也会是一个单独的URL/Django视图,与该资源的普通HTML对应。

撰写回答