问题
I am completely novice at AJAX. I am familiar with HTML/CSS, jQuery and beginner at GAE and Python.
In an effort to understand how AJAX works, I would like to know how AJAX might be used (actual code) in this example below. Let's use a reddit-like example where vote ups/downs are ajaxified:
Here is the Story Kind:
class Story(ndb.Model):
title = ndb.StringProperty(required = True)
vote_count = ndb.IntegerProperty(default = 0)
The HTML would look like this:
<h2>{{story.title}}</h2>
<div>
{{story.vote_count}} | <a href="#">Vote Up Story</a>
</div>
How does AJAX fit inside here?
回答1:
Ok Sir here we go... A simple app with one story and infinite votes... ;-)
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()})))
and finally
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>
Assemble, read it's simple enough and run. If you need a working git example just comment.
githublink (as from comments)
回答2:
Here is a little prototype web app on GitHub to test how to handle error messages in HTML form submissions with AJAX, Python and Google App Engine. It will give a starting point to see how these three pieces of technology mesh together. You can test this "app" on https://ajax-prototype.appspot.com/
Here is how it works on the client-side:
This htlm form submission is used:
<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>
It will trigger the JavaScript function
ajaxScript
:function ajaxScript() { var input = $("#input").val(); $.ajax({ type: "POST", url: "/", data: JSON.stringify({ "name": input }), dataType: "json" }) .done(function(jsonResponse) { $("#error").html(jsonResponse.message); }); }
The jQuery
.ajax()
method handles the request while the.done()
method will eventually handle the response that it gets from the server.
On the server-side:
The
main.py
file handles the server side of the business using our handler classAjaxHandler
, which inherits from the GAE builtin classwebapp2.RequestHandler
Within this class, the
post
method handles the AJAX request: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}))
Basically, the handy
json
module provides the two key Python ingredientsjson.loads
handles the data that the browser sends to the server.json.dumps
handles the data sent by the server in response to the browser's request.- The
self.request.body
argument ofjson.loads
is the only less common piece of GAE that is used in the process, as it is specific to the task. As its name suggests, it gets the body from the Ajax request sent by the client.
来源:https://stackoverflow.com/questions/22052013/how-to-use-ajax-with-google-app-engine-python