如何遍历一对多关系的查询结果?
我对如何过滤和显示一对多关系有点困惑。
根据这个问题和这篇文章(还有我之前的问题),我在Item之外创建了一个新的引用属性Tag:
class Item(db.Model):
...
title = db.StringProperty()
url = db.StringProperty()
image_source_url = db.StringProperty()
....
class Tag(db.Model):
item = db.ReferenceProperty(Item, collection_name = "image_tags")
tag = db.StringProperty()
我在Tag中添加了两个新项,现在表格看起来是这样的:
Key: ahNzYz...
ID: 269
Key Name:
item: ahNzYXJh...
Item: id=268
tag: glam
Key: ahNxyz...
ID: 270
Key Name:
item: ahNzYXJh...
Item: id=264
tag: casual
在我的SortFormHandler中,我进行了这个查询,并尝试遍历结果:
class SortFormHandler(webapp.RequestHandler):
def get(self):
query = Tag.all()
query.filter("tag", "glam")
for item in query.image_tags:
self.response.out.write("""<a href="%s"><image src="%s" height="110">%s</a>""" %
(item.url, item.image_source_url, item.title) )
这导致了属性错误:
AttributeError: 'Query' object has no attribute 'image_tags'
我尝试了其他组合,但都没有成功。如果有人能解释一下这个是怎么回事,我就能理解如何遍历结果了。
谢谢。
更新
我尝试了Daniel Roseman的回答,像这样:
for tag in query:
self.response.out.write("tag is: %s" % tag.tag)
for item in tag.image_tags:
self.response.out.write("""<a href="%s"><image src="%s" height="110">%s</a>""" %
(item.url, item.image_source_url, item.title) )
但这给出了
AttributeError: 'Tag' object has no attribute 'image_tags'
有什么建议可以解决这个问题吗?
更新 2
我看到在Tag表中,引用项的ID存储在item这一列下。我该如何获取这个ID?我尝试了
tag.item
在这一行
for tag in query:
self.response.out.write("tag is: %s. ID is: %s" % (tag.tag, tag.item))
但这只返回了对象:
tag is: glam. ID is: <__main__.Item object at 0x06875EB0>
更新 3
好的,我找到了获取引用项的键名的方法:
for tag in query:
self.response.out.write(ID is: %s" % (tag.item.key()))
所以
tag.item.key()
返回了我需要使用的项的键。我该如何获取该项的url和title等信息?我该如何显示它?
更新 4
这似乎有效(至少对一个标签来说):
for tag in query:
referenced_item_key = tag.item.key()
item = Item.get(referenced_item_key)
self.response.out.write("""<a href="%s"><image src="%s" height="110">%s</a>""" %
(item.url, item.image_source_url, item.title) )
注意:名称有点混淆,这里的item指的是Tag中的引用列:
referenced_item_key = tag.item.key()
我应该把这个项命名为其他名字:
item = Item.get(referenced_item_key)
相关问题:
1 个回答
1
这里你需要用到两个循环。query 是一个包含标签对象的列表。每个标签对象里面又有一个物品的列表。所以你需要先遍历 query,然后再遍历每个标签里的物品。
不过,还有第二个问题:ReferenceProperty 的方向是错的。根据我的理解,ReferenceProperty 就像普通 Django 中的 ForeignKey:也就是说,它是一种一对多的关系,其中定义这个属性的模型是“一”的那一方。但你似乎想要每个标签对应多个物品,然后再去遍历这些物品:所以你需要把 ReferenceProperty 放在物品模型上。
这样,你就可以进行两个循环了:
for tag in query:
self.response.out.write('header for tag %s' % tag.tag)
for item in tag.image_tags:
self.response.out.write('detail for each item')