如何遍历一对多关系查询结果?

时间:2011-01-28 18:34:02

标签: python google-app-engine google-cloud-datastore one-to-many

我对如何过滤和显示一对多关系感到困惑。

关注this questionthis articleand my previous question)除了Tag之外,我创建了一个新的ReferenceProperty Item

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的answer就像这样:

        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()

返回我需要使用的项的键。如何获取该项目的urltitle等?我该如何显示它?

更新4

这似乎有用(至少对于1个标签):

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 个答案:

答案 0 :(得分:1)

这里需要两个循环。 query是Tag对象的列表。每个对象本身都有一个项目列表。因此,您需要遍历query,然后遍历每个标记的项目。

然而,还有第二个问题:ReferenceProperty是错误的方式。据我所知,ReferenceProperty就像普通Django中的ForeignKey:换句话说,是一对多关系,其中定义属性的模型是关系的“一”侧。但是你似乎想要为每个Tag添加多个Items,然后循环遍历:所以你需要将ReferenceProperty放在Item模型上。

然后,你可以做两个循环:

 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')