在Django中对相关对象进行分组

时间:2011-10-31 11:24:18

标签: python django django-views

我正在构建一个应用程序,您可以在其中搜索数据库中的对象(假设您搜索的对象是人物)。我想要做的是将相关对象分组,例如已婚夫妇。换句话说,如果两个人拥有相同的姓氏,我们假设他们已婚(不是一个很好的例子,但你明白了)。姓氏是唯一标识两个人已婚的人。 在搜索结果中,我想展示彼此相邻的已婚夫妇,以及所有其他人。

假设您搜索“John”,这就是我想要的:

John Smith - Jane Smith
John Adams - Nancy Adams
John Washington
John Andersson
John Ryan

然后,每个名称都是该人员个人资料页面的链接。

我现在拥有的是一个找到所有对的函数,并返回一个元组列表,其中每个元组都是一对。问题是在搜索结果中,一对中的每个名称都会列出两次。 我对搜索查询(Person.objects.filter(name__contains =“John”))进行查询,并将该查询的结果发送给匹配函数。然后,我将原始查询集和匹配函数结果发送到模板。 我想我可以排除匹配函数找到匹配的每个人,但我不知道,但这是最有效的解决方案吗?

编辑:

正如我在评论中写的那样,我想要匹配的实际字符串并不相同。引用自己:

  

事实上,我想要匹配的字符串并不相同,而是它们   看起来更像是这样:“foo2(bar13)” - “foo2(bar14)”。也就是说,如果两个   字符串具有相同的foo id(2),如果bar id是奇数   (13),那么它的匹配是bar id + 1(14)。我有一个常规的   表达式找到这些匹配

1 个答案:

答案 0 :(得分:2)

首先按姓氏排序对象:

def keyfun(p):
    return p.name.split()[-1]

persons = sorted(Person.objects.all(), key = keyfun)

然后使用groupby:

from itertools import groupby
for lname, persons in groupby(persons, keyfun):
    print ' - '.join(p.name for p in persons)

更新是的,此解决方案也适用于您的新要求。您只需要一种稳定的方法来为每个项目生成密钥,并用它替换密钥管的主体:

from re import findall
def keyfun(p):
    v1, v2 = findall(p.name, '\d+')
    tot = int(v1) + int(v2) % 2
    return tot

关于如何为每个项目生成密钥的描述不够清晰,尽管您应该能够通过上面的示例自行解决。