第三部分:Django与Prototype:Ajax Request(非对称模式发送数据)
Ajax另一个常用的功能是发送数据到服务器但不强制用户重新加载他们所在的整个页面。在Django与Ajax教程的第三节中我们将要向Server发送Django生成表单的内容。(Request和Upater不同之处是Requset对象不需要服务器进行应答,下面将更加深入的进行解释。)你可以从这里得到本节例子的源码。
Ajax Request语法和目的
Ajax.Requst负责的是从网页到服务器的单向交流。它大概就像网页说“嗨,这家伙创建了一个帐号,我已经知道该怎么做了,所以不要理会给我的指令”,或者可能像网页说:“server my man, you have a new comment to hold onto until someone can approve it.(你有一条新的评论需要保持直到有人批准它--这句话不太明白是嘛意思)”当你希望使用Ajax.Request从服务器得到一些HTML来填充div,或者从服务器得到任何种类的响应时,它是没有用的,你将什么也得不到。
Ajax.Request
的语法为:
new Ajax.Request(‘url/to/send/to’, config)
第一个参数是你发送数据的目标
URL
,第二个是一个包含配置数据的字典变量。跟
Ajax Updater
一样你需要指定要发送的数据,发送方式,是否异步(它通常是异步的,除非你和用户有仇
…
)。这里有两个可能在实际中使用的例子:
var post = ‘id=’ + id;
new Ajax.Request(‘category/remove/’, {asynchronous: true, method:‘post’, postBody:post});
new Ajax.Request(‘category/remove/’, {asynchronous: true, method:‘post’, postBody:post});
或
new Ajax.Request(‘category/add’, {asynchronous:
true, parameters:Form.serialize(form)});
这两个例子中的第二个例子要复杂一些,因为它使用
Prototype
中的
Form
库来序列化一个表单。第一次看到它可能会觉得有点混乱,但在我们的例子中将会看一下它到底如何在模板和视图中设置和转化被序列化的表单。
在Django应用中使用Ajax.Request
在文章开始我们就谈到,我们要创建一个有简单表单的页面,当我们按下提交按钮的时候表单就会被发送到服务器。在发送后我们将会使用Prototype的Form库来重置这个表单。
尽管略有牵强,但这个例子的确与真实用例很相似。你已经知道在没有任何服务器指令的时候如何回应某些刺激,但你还是需要将所发生的一切通知服务器。一种情况是当你从一个页面上删除内容的时候:你可以在客户端使用JavaScript从问题中移除元素,但仍必须让服务器知道哪些元素被删除。
总之,让我们开始编码吧。
修改urls.py
我们将在ajaxapp/urls.py文件中添加两个入口。一个将用来显示页面,另一个将用来处理发送过来的已完成表单。
我们把ajaxapp/urls.py修改成这样:
from django.conf.urls.defaults import *
urlpatterns = patterns(‘ajaxproject.ajaxapp.views’,
(r‘^$’, ‘index’),
(r‘^send/$’, ’send’),
)
urlpatterns = patterns(‘ajaxproject.ajaxapp.views’,
(r‘^$’, ‘index’),
(r‘^send/$’, ’send’),
)
十分简单。接下来让我们处理Views。
创建视图
我们需要在视图中添加两个函数---index和send。我们也会将表单和视图写在一起(在一个大的工程中最好将模型从视图中独立出来)。
模型会有两个字段,一个character字段和一个textarea字段。我们将通过newforms库来创建它,像下面这样:
class CommentForm(forms.Form):
name = forms.CharField(required=False)
text = forms.CharField(widget=Textarea, required=False)
name = forms.CharField(required=False)
text = forms.CharField(widget=Textarea, required=False)
现在有了(简单的)表单,我们需要去创建两个视图函数。首先,我们需要使用
index
函数去渲染
amaxapp/index.html这个
模板,同时还要确保将一个“
form
”变量传给了它。
def index(request):
form = CommentForm()
return render_to_response("ajaxapp/index.html",{ ‘form’ : form})
form = CommentForm()
return render_to_response("ajaxapp/index.html",{ ‘form’ : form})
我们还需要创建
send
函数来处理接收到的表单数据。为了简单,我们仅仅向标准输出设备打印一个格式化好的输入文本(也就是说你可以从你的开发服器终端窗口上来看到输出结果)。
def send(request):
post = request.POSTfor key in post.keys():
print "key: " , key , "; value: " , post[key]
post = request.POSTfor key in post.keys():
print "key: " , key , "; value: " , post[key]
实际应用中你可能会根据接收到的数据创建一个新的
Model
实例,或者可能通过新值来更新现有实例。幸好很容易从表单中获取键值。
请注意,因为我们接收到的是一个通过newforms库创建的、已经被序列化的表单,它很容易使用已经接收到的request.POST数据来转换成为一个已创建的表单的实例。就像下面这样简单:
def send(request):
post = request.POST
form = CommentForm(post)
post = request.POST
form = CommentForm(post)
还不算太坏。如果你用
form_for_model
方法创建了一个表单将会特别的方便,此时,你可以简单的调用
form.save()
方法来创建一个新的
Model
实例。
好了,如果我们把模型和视图函数放在一块,那么整个的views.py文件将会是这样:
from django.shortcuts
import render_to_response
from django import newforms as forms
class CommentForm(forms.Form):
name = forms.CharField(required=False)
text = forms.CharField(widget=forms.Textarea, required=False)
def index(request):
form = CommentForm()
return render_to_response( "ajaxapp/index.html",
{ ‘form’ : form }
)
def send(request):
post = request.POST
for key in post.keys():
print "key: " , key , "; value: " , post[key]
from django import newforms as forms
class CommentForm(forms.Form):
name = forms.CharField(required=False)
text = forms.CharField(widget=forms.Textarea, required=False)
def index(request):
form = CommentForm()
return render_to_response( "ajaxapp/index.html",
{ ‘form’ : form }
)
def send(request):
post = request.POST
for key in post.keys():
print "key: " , key , "; value: " , post[key]
创建模板
我们这个例子只需要一个简单的模板,它将用来显示前面创建的CommentForm表单,并且它还将有一些辅助的javascript来覆盖表单缺省的提交处理。这个模板扩展自我们在教程第一部分创建的ajaxapp/base.html模板。
{% extends ‘ajaxapp/base.html’ %}
{% block content %}
< script type ="text/javascript" >
function send_form(form) {
new Ajax.Request("send/", {asynchronous:true, parameters:Form.serialize(form)});
Form.reset(form);
return false;
}
</script>
< h1 > Submit Comments </h1>
< form method ="post" action ="." onsubmit ="return send_form(this);" >
< table >
` form `
< tr >
< td > </td>
< td >
< input type ="submit" value ="Send!" />
</td>
</tr>
</table>
{% endblock %}
{% block content %}
< script type ="text/javascript" >
function send_form(form) {
new Ajax.Request("send/", {asynchronous:true, parameters:Form.serialize(form)});
Form.reset(form);
return false;
}
</script>
< h1 > Submit Comments </h1>
< form method ="post" action ="." onsubmit ="return send_form(this);" >
< table >
` form `
< tr >
< td > </td>
< td >
< input type ="submit" value ="Send!" />
</td>
</tr>
</table>
{% endblock %}
注意我们是如何来覆盖表单的onsubmit缺省方法的。因为我们在调用中返回了false,所以缺省的提交机处理将永不被触发。此外,我们还使用了Prototype的Form库中的一个有用的方法在发送完数据后来重置表单。
我们还使用了Form库中的一个便利的方法来序列化这个表单。可以使用文章开头附近第一个例子的语法来创建你自己任意的post strings…如果行的话它会非常容易被序列化。
结束
现在我们已经完成了urls的添加,模板的创建,以及视图的编码:一切搞定!
运行一下开发服务器
python manage.py runserver
往表单字段里输入一些数据然后点击提交按钮。你将看到所发出的消息会从开发服务器的终端窗口上被打印出来。
花一些时间来多加练习,后面还有第四部分等着你呢。我将在第四部分中介绍使用Scriptaculous来拖放列表。
转载于:https://blog.51cto.com/ddkangfu/75417