2013-02-09 174 views
1

我对Python相对较新,来自PHP世界。在PHP中,我会经常取一行,它将对应于数据库中的对象,称为User,并在将用户对象传递给我的查看页面之前向其添加属性。 例如,用户具有属性电子邮件,名称和ID。 我从数据库中获得5个用户,并且在for循环中,我为用户分配了一个动态属性,例如图像。将动态属性添加到数据存储对象

这似乎并不在Python /谷歌App Engine数据存储模型的工作(我认为它具有比Python的数据存储模型做多),在for循环中。它可以在for循环中工作(这意味着我可以在for循环中引用user.image,但是一旦for循环结束,所有对象似乎都不再具有新的属性图像了。

这是一个代码示例:

# Model 
Class User(ndb.Model): 
    email = ndb.StringProperty() 
    name = ndb.StringProperty() 


# And then a function that returns a list of users 
users = User.get_users() 

user_list = [] 
# For loop 
for user in user: 
    # For example, get image 
    user.image = Image.get_image(user.key) 
    user_list.append(user) 

    # If I print or log this user in the for loop, I see a result 
    logging.info(user.image) # WORKS! 

for ul in user_list: 
    print ul.image # Results in None/ATTR Error 

我搜索的形式,但我无法找到任何东西给我任何人都可以解释为什么这种情况正在发生,以及如何实现这一目标?

+0

这应该肯定有效。你确定这是确切的代码吗?您在第一个和第二个循环之间没有做任何事情,这可能会导致实例从数据存储中重新获取? – 2013-02-10 01:31:53

+0

get_users()可能是一个查询,在这种情况下,第二个循环将重新获取没有动态属性的用户。 – 2013-02-10 06:27:39

+0

丹尼尔,你是对的!我的错误家伙,我打印整个对象,出于某种原因(也许你可以解释),只有原始属性打印出来。但是,如果我直接调用动态属性,就像上面那样(print ul.image),它就可以工作。抱歉! – kevin 2013-02-11 01:03:02

回答

0

尝试使用Expando Model

有时你不想提前声明你的属性。一个 特殊型号的子类,为Expando,使得分配(只要它不与 下划线开始)的任何属性被保存到数据存储改变其实体 的行为。

+0

谢谢,谢伊,这是一个可能的解决方案,也许最终会成为最好的。但是,我对Expando类的理解更多的是将动态属性放入数据存储区,而不是添加要在视图页上显示的属性,对吗? – kevin 2013-02-09 21:25:57

+0

我试图避免使用Expando来从数据存储角度不需要它的类(以避免意外地将属性放置到不应该有它们的实体的风险) – kevin 2013-02-09 21:28:30