【问题标题】:How do I share data between pages on Google App Engine如何在 Google App Engine 上的页面之间共享数据
【发布时间】:2011-03-24 04:55:26
【问题描述】:

我是一名新手程序员,正在开发我的第一个网络应用程序(使用 App Engine),请原谅我的无知。

我一直在修改 Google 提供的 Hello World 程序,试图让它做我想做的事情。

在他们的演示 (http://code.google.com/appengine/docs/python/gettingstarted/templates.html) 中,他们有 2 个创建 2 个页面的类 - 一个是 index.html,另一个处理表单,通过将表单数据放入数据库,然后重定向回主页,从数据库加载信息。

我想在主页上有一个表单,用户提交一个字符串,在该表单上执行各种操作,并将输出显示在主页上。

问题是用户提交的表单中的数据进入表单处理程序页面,我不知道如何将输出返回到主页。

【问题讨论】:

    标签: google-app-engine web-applications


    【解决方案1】:

    在不同提交之间持久保存数据的自然方法是使用Datastore
    如果出于练习目的,您不想使用数据存储,则必须将数据传递给视图并在每个 Web 请求之间使用一些 hidden 字段将其读回。

    让我们看一个简单的 quick&dirty 示例:一个将整数一个一个求和的网络应用程序。

    application.py

    import os
    from google.appengine.ext import webapp
    from google.appengine.ext.webapp import template
    from google.appengine.ext.webapp.util import run_wsgi_app
    
    class Sum(webapp.RequestHandler):
        def get(self):
            path = os.path.join(os.path.dirname(__file__), 'index.html')
            template_values = {"total":0}
            self.response.out.write(template.render(path, template_values))
    
        def post(self):    
            value = self.request.get("value")
            total = self.request.get("total")
            total = int(total) + int(value)
            path = os.path.join(os.path.dirname(__file__), 'index.html')
            template_values = {"value":value,
                               "total":total
                              }
            self.response.out.write(template.render(path, template_values))
    
    application = webapp.WSGIApplication(
                                     [('/', Sum),
                                      ('/sum', Sum)],
                                     debug=True)
    
    def main():
        run_wsgi_app(application)
    
    if __name__ == "__main__":
        main()
    

    要将数据传递给index.html 视图,使用template.render 函数将一个字典变量传递给视图:

    template.render(path_to_the_view, template_values)
    

    index.html

    <html>
    <body>
      <form action="/sum" method="post">
        <p>
        <label for="value">Value to sum:
        <input type="text" name="value"><br>
        <input type="submit" value="Submit">
        <input type="hidden" name="total" value="{{ total }}">
        </p>
      </form>
      Last value submitted: {{ value }}| Total:{{ total }}
    </body>
    </html>
    

    index.html 视图使用字典键 valuetotal 显示结果并使用 hidden 字段将总数提交回控制器。

    结果如下:

    【讨论】:

    • 啊!我有一些问题。 1. 是否有可能用 2 个不同的类来做到这一点?我注意到您将 2 个类合并为一个... 2. 如果您使用数据存储跨类进行通信,那将如何工作?似乎如果用户 A 提交了一个值 - 例如“3”并提交了它,那么总计将等于 3,并且您将其存储在您的数据存储中。然后,用户 B 提交了 4,它会为他返回 7,而不是预期的 4。您是否还需要为每个用户存储一个唯一的 ID?
    • @Jeremy 1) 是的 - 它所在的处理程序类无关紧要。 2) 这正是您正在查看的演示所做的。
    • @jeremy 1. 您可以将代码组织在几个满足您需求的类中;没关系。 2. 如果您想在我的简单示例中使用数据存储,是的,您应该区分每个用户。
    【解决方案2】:

    index.html模板生成的HTML表单有如下form标签:

    <form action="/sign" method="post">
    

    这意味着当用户点击提交按钮时,表单的数据将被发送到/signaction URL 确定使用哪个处理程序。首先,我们查看您的app.yaml 文件以查看将使用哪个脚本来处理请求:

    handlers:
    - url: /.*
      script: helloworld.py
    

    所有 URL 都由helloworld.py 处理,让我们看看那里:

    application = webapp.WSGIApplication(
                                         [('/', MainPage),
                                          ('/sign', Guestbook)],
                                         debug=True)
    

    基于此,我们可以看到/sign URL 是由Guestbook 请求处理程序处理的。如果您希望表单提交由不同的页面处理,您需要更改表单提交到的页面(form 标记中的action 属性)或更改分配给指定的请求处理程序。

    【讨论】:

    • 抱歉 - 我不是很清楚。我想要的是一种在主页上使用请求处理程序的一些输出的方法。这可能吗,还是我应该将用户重定向到请求处理程序页面(在这种情况下是 /sign)?
    • 如果你的一些输出应该在你的主页和 /sign 页面上生成,那么也许你可以将它重构为一个单独的函数(在两个请求处理程序之外,或者作为其中之一的静态方法他们)并从两者中调用它。或者你可以使用模板继承来达到这个效果。取决于你想做什么。
    【解决方案3】:

    我不明白您为什么要将输出返回到主页。在提交表单时,控件转到处理程序类。现在,您可以以任何您希望的方式在您的 requesthandler 类中使用此表单数据。

    如果您希望将此请求处理程序中的一些数据传输到您的主页,您可以创建全局变量或创建另一个带有隐藏输入的表单来传输数据。希望这能回答你的问题。

    【讨论】:

    • 这正是我想要做的 - 抱歉这么无知,但是我将如何创建一个全局变量并将其传递回主页类,或者创建一个具有隐藏输入的表单并传递回来了吗?
    • @Jeremy:请参阅创建全局变量,您需要在 var1=None 之类的导入语句之后定义它,并且在您想使用它的任何函数中,您必须像 global var1 一样定义它。希望这能解决您的问题。
    【解决方案4】:

    如果您使用 webapp.requestHandler,request 是一个字典对象,其中包含用户提交的所有数据。所以,这里是你获取数据的方式

    class SubmitHandler (webapp.RequestHandler):
      name = self.request.get ('name')
      email = self.request.get ('emil')
      # do whatever
    

    这假定“姓名”和“电子邮件”是表单中的字段。

    【讨论】:

      【解决方案5】:

      我建议你使用 Ajax 表单,这里有几个示例的链接(使用 jquery) jquery ajax form handling

      基本上,您可以像往常一样定义一个表单,但不是将发布请求发送到另一个页面,而是将请求发布到服务器处理程序,该处理程序执行某些操作并通常以 json 格式传回响应,然后您可以处理该响应使用 javascript 并使用结果更新主页。

      【讨论】:

        猜你喜欢
        • 2016-05-04
        • 1970-01-01
        • 2015-02-27
        • 2014-09-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多