过滤标签列表

时间:2011-08-30 18:07:32

标签: django google-app-engine filter multi-query

我正在尝试选择我的Django数据库中的所有歌曲,其中的标签是给定列表中的任何一个。有一个Song模型,一个Tag模型和一个SongTag模型(用于多对多关系)。

这是我的尝试:

taglist = ["cool", "great"]
tags = Tag.objects.filter(name__in=taglist).values_list('id', flat=True)
song_tags = SongTag.objects.filter(tag__in=list(tags))

此时我收到了一个错误:

DatabaseError: MultiQuery does not support keys_only.

我错了什么?如果你可以提出一个完全不同的方法来解决这个问题,那么它也非常受欢迎!

编辑:我应该提到我在django-nonrel Google AppEngine 上使用Django

3 个答案:

答案 0 :(得分:6)

您不应该与AppEngine使用m2m关系。 NoSQL数据库(和BigTable就是其中之一)通常不支持JOIN,程序员应该对数据结构进行非规范化。这是一个深思熟虑的设计方案:虽然您的数据库将包含冗余数据,但您的读取查询将更加简单(无需组合来自3个表的数据),这反过来又使DB服务器的设计更加简单(当然这是为了优化和缩放而制作的)

在您的情况下,您应该摆脱Tag和SongTag模型,只需将标签作为字符串存储在Song模型中。我当然假设Tag模型只包含id和name,如果Tag实际上包含更多数据,你仍然应该有Tag模型。在这种情况下,歌曲模型应包含tag_id和tag_name。正如我在上面解释的那样,这个想法是为了更简单的查询而引入冗余

答案 1 :(得分:3)

请让ORM为您构建查询:

song_tags = SongTag.objects.filter(tag__name__in = taglist)

答案 2 :(得分:0)

您应该尝试仅使用一个查询,以便Django也只使用连接生成一个查询。 这样的事情应该有效:

Song.objects.filter(tags__name__in=taglist)

您可能需要更改此示例中的某些名称(很可能是tags中的tags__name__in),请参阅https://docs.djangoproject.com/en/1.3/ref/models/relations/