在Google App Engine中更新数据

0 投票
3 回答
989 浏览
提问于 2025-04-15 11:18

我正在尝试我的第一个谷歌应用引擎项目——为我参与的一个运动队创建一个简单的球员统计数据库。给定这个模型:

class Player(db.Model):
    """ Represents a player in the club. """

    first_name = db.StringProperty()
    surname = db.StringProperty()
    gender = db.StringProperty()

我想做一个基本的网页界面,用来创建和修改球员。我的代码结构大致是这样的:

class PlayersPage(webapp.RequestHandler):
    def get(self):
        # Get all the current players, and store the list.
        # We need to store the list so that we can update
        # if necessary in post().
        self.shown_players = list(Player.all())

        # omitted: html-building using django template

这段代码生成了一个非常简单的HTML页面,里面有一个表单和一个表格。这个表格为每个球员显示一行,长得像这样:

  <tr>
    <td><input type=text name="first_name0" value="Test"></td>
    <td><input type=text name="surname0" value="Guy"></td>
    <td><select name="gender0">
        <option value="Male" selected>Male</option>
        <option value="Female" >Female</option>
      </select></td>
  </tr>
  <!-- next row: first_name1, etc. -->

我的想法是把我用到的球员实例存储在self.shown_players里,这样我就可以在同一个类的post()方法中更新球员,如果有需要的话,方法是:

def post(self):
    # some code skipped

    for i, player in enumerate(self.shown_players):
        fn = self.request.get('first_name'+str(i)).strip()
        sn = self.request.get('surname'+str(i)).strip()
        gd = self.request.get('gender'+str(i)).strip()
        if any([fn != player.first_name,
                sn != player.surname,
                gd != player.gender]):
            player.first_name = fn
            player.surname = sn
            player.gender = gd
            player.put()

但是,这样做不行,因为当post()方法被调用时,self.shown_players并不存在。我猜每次访问页面时,应用引擎都会创建这个类的新实例。

我尝试了同样的想法,把shown_players放在类或模块级别(并把它叫做global),但这也没有成功,原因我也搞不清楚。比如:

shown_players = []
class PlayersPage(webapp.RequestHandler):
    def get(self):
        # Get all the current players, and store the list.
        # We need to store the list so that we can update
        # if necessary in post().
        global shown_players
        shown_players[:] = list(Player.all())

shown_playersget()方法中似乎有正确的值,因为HTML生成得很正常,但在post()方法中却是空的。

我该怎么办呢?

编辑:谢谢大家。答案(“只需再次获取球员!”)应该是显而易见的 :-) 也许有一天我会看看memcache,但我不指望球员列表在不久的将来超过30个..

3 个回答

1

我从来没有尝试过构建谷歌应用引擎的应用,但我知道它在处理数据库等方面和Django有点相似。

我觉得不应该把东西存储在全局变量里,而是应该把每次操作都当作独立的事务来处理。你能成功获取请求,是因为你做了该做的事情,重新从数据库请求信息。

如果你想在你的POST函数中更新一个玩家的信息,你可能需要传入这些详细信息,[再根据这些详细信息查找玩家],然后随意修改它们。括号里的部分就是你缺少的步骤。

2

在你的post方法中,在"for"循环之前,先从存储的地方获取玩家列表:

def post(self):
    # some code skipped

    self.shown_players = Player.all().fetch()
    for i, player in enumerate(self.shown_players):
      ...
2

每次请求时,你都是在处理同一个类的新实例。这就是为什么你不能在 get() 方法中创建一个变量,然后在 post() 方法中使用它的值。你可以做的事情是,要么在 post() 方法中重新获取这些值,要么把数据存储在 memcache 中。

关于 memcache 的详细信息可以参考这里的文档:

http://code.google.com/intl/de-DE/appengine/docs/python/memcache/

撰写回答