How to use AJAX with Google App Engine (Python)

前端 未结 2 1284
被撕碎了的回忆
被撕碎了的回忆 2020-12-25 08:08

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 h

相关标签:
2条回答
  • 2020-12-25 08:48

    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)

    0 讨论(0)
  • 2020-12-25 09:10

    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 class AjaxHandler, which inherits from the GAE builtin class webapp2.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 ingredients

      • json.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 of json.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.
    0 讨论(0)
提交回复
热议问题