如何将 AJAX 与 Google App Engine (Python) 结合使用
Posted
技术标签:
【中文标题】如何将 AJAX 与 Google App Engine (Python) 结合使用【英文标题】:How to use AJAX with Google App Engine (Python) 【发布时间】:2014-03-29 21:47:54 【问题描述】:我完全是 AJAX 的新手。我熟悉 html/CSS、jQuery 和 GAE 和 Python 的初学者。
为了了解 AJAX 的工作原理,我想知道在下面的示例中如何使用 AJAX(实际代码)。让我们使用一个类似 reddit 的例子,其中投票的上升/下降是 ajaxified:
这是故事类型:
class Story(ndb.Model):
title = ndb.StringProperty(required = True)
vote_count = ndb.IntegerProperty(default = 0)
HTML 看起来像这样:
<h2>story.title</h2>
<div>
story.vote_count | <a href="#">Vote Up Story</a>
</div>
AJAX 如何融入其中?
【问题讨论】:
【参考方案1】:好的,先生,我们开始...一个简单的应用程序,一个故事和无限投票... ;-)
app.yaml
application: anotherappname
version: 1
runtime: python27
api_version: 1
threadsafe: true
default_expiration: "0d 0h 5m"
libraries:
- name: jinja2
version: latest
- name: webapp2
version: latest
handlers:
- url: .*
script: main.app
main.py
import logging
from controllers import server
from config import config
import webapp2
app = webapp2.WSGIApplication([
# Essential handlers
('/', server.RootPage),
('/vote/', server.VoteHandler)
],debug=True, config=config.config)
# Extra Hanlder like 404 500 etc
def handle_404(request, response, exception):
logging.exception(exception)
response.write('Oops! Naughty Mr. Jiggles (This is a 404)')
response.set_status(404)
app.error_handlers[404] = handle_404
models/story.py
from google.appengine.ext import ndb
class Story(ndb.Model):
title = ndb.StringProperty(required=True)
vote_count = ndb.IntegerProperty(default = 0)
controllers/server.py
import os
import re
import logging
import config
import json
import webapp2
import jinja2
from google.appengine.ext import ndb
from models.story import Story
class RootPage(webapp2.RequestHandler):
def get(self):
story = Story.get_or_insert('Some id or so', title='A voting story again...')
jinja_environment = self.jinja_environment
template = jinja_environment.get_template("/index.html")
self.response.out.write(template.render('story': story))
@property
def jinja_environment(self):
jinja_environment = jinja2.Environment(
loader=jinja2.FileSystemLoader(
os.path.join(os.path.dirname(__file__),
'../views'
))
)
return jinja_environment
class VoteHandler(webapp2.RequestHandler):
def post(self):
logging.info(self.request.body)
data = json.loads(self.request.body)
story = ndb.Key(Story, data['storyKey']).get()
story.vote_count += 1
story.put()
self.response.out.write(json.dumps(('story': story.to_dict())))
最后
views/index.html
<!DOCTYPE html>
<html>
<head>
<base href="/">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
</head>
<body>
<h2>story.title</h2>
<div>
<span class="voteCount">story.vote_count</span> | <a href="javascript:VoteUp('story.key.id()');" >Vote Up Story</a>
</div>
<script>
function VoteUp(storyKey)
$.ajax(
type: "POST",
url: "/vote/",
dataType: 'json',
data: JSON.stringify( "storyKey": storyKey)
)
.done(function( data ) // check why I use done
alert( "Vote Cast!!! Count is : " + data['story']['vote_count'] );
$('.voteCount').text(data['story']['vote_count']);
);
;
</script>
</body>
</html>
组装,读起来很简单,然后运行。如果您需要一个有效的 git 示例,请发表评论。
githublink(来自 cmets)
【讨论】:
@haopei 对不起,我忘了你。给你github.com/jimmykane/gae-voting-ajax-example。我希望你给它加星 ;-) 再次感谢@Jimmy Kane。 你能简单解释一下 self.request.body 的作用吗?我在 webapp 和 appengine 文档上进行了搜索,但发现很少。文档中似乎几乎没有定义它。谢谢。 @haopei webapp-improved.appspot.com/guide/request.html 看看这个。它记录在那里......如果您需要更多帮助,请提及。 @haopei 日期时间属性不是 json 可序列化的。尝试像这样排除该属性:story.to_dict(exclude='my_datetime')
,然后将其转换并附加到字典。在此处查看 to_dict 以及如何使用它 developers.google.com/appengine/docs/python/ndb/… 。日期时间也很痛苦。如果您需要进一步的帮助,请在此处再次提及,我将尝试添加日期时间序列化技术【参考方案2】:
这是 GitHub 上的一个小 prototype 网络应用程序,用于测试如何使用 AJAX、Python 和 Google App Engine 处理 HTML 表单提交中的错误消息。它将为了解这三项技术如何融合在一起提供一个起点。你可以在https://ajax-prototype.appspot.com/上测试这个“应用程序”
这是它在客户端的工作方式:
这个htlm form submission被使用了:
<form method="post" action="javascript:ajaxScript();">
<label>Please pick a name</label>
<input id="input" type="text">
<input type="submit">
<div id="error" style="color:red"></div>
它会触发JavaScript functionajaxScript
:
function ajaxScript()
var input = $("#input").val();
$.ajax(
type: "POST",
url: "/",
data: JSON.stringify(
"name": input
),
dataType: "json"
)
.done(function(jsonResponse)
$("#error").html(jsonResponse.message);
);
jQuery .ajax()
方法处理请求,而 .done()
方法最终将处理它从服务器获得的响应。
在服务器端:
main.py
文件使用我们的 handler class AjaxHandler
处理业务的服务器端,它继承自 GAE 内置类 webapp2.RequestHandler
在这个类中,post
方法处理 AJAX 请求:
def post(self):
data = json.loads(self.request.body)
username = data["name"]
if not re.match(r"^[a-zA-Z0-9_-]3,20$", username):
if len(username) < 3:
message = "Your name must be at least 3 characters long."
else:
message = "Allowed characters are \
a-z, A-Z, 0-9, underscores \
and hyphens."
else:
message = "Congrats!"
self.response.write(json.dumps("message": message))
基本上,方便的 json
模块提供了两个关键的 Python 成分
json.loads
处理浏览器发送到服务器的数据。
json.dumps
处理服务器响应浏览器请求发送的数据。
json.loads
的 self.request.body
参数是进程中唯一不太常见的 GAE 部分,因为它特定于任务。顾名思义,它从客户端发送的 Ajax 请求中获取正文。
【讨论】:
以上是关于如何将 AJAX 与 Google App Engine (Python) 结合使用的主要内容,如果未能解决你的问题,请参考以下文章
如何将过滤器与 Google App Engine 的 app.yaml 中的 servlet 相关联?
如何将 Django 的标记模板标签与 Google App Engine WebApp 框架一起使用
我如何使Figma API与Google App脚本API一起使用?
将 JWT 与 Google App Engine 结合使用