2011-10-31 89 views
0

我正在構建一個應用程序,您可以在其中搜索數據庫中的對象(讓我們假設您搜索的對象是人員)。我想要做的是將相關對象分組,例如已婚夫婦。換句話說,如果兩個人有相同的姓氏,我們假設他們已婚(不是一個很好的例子,但你明白了)。姓氏是唯一標識兩個人結婚的人。 在搜索結果中,我想顯示彼此相鄰的已婚夫婦,以及所有其他人自己。Django中的組相關對象

讓我們說你搜索「約翰」,這就是我想要的:

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),並且條形碼編號爲奇數 (13),則其匹配是條形碼id + 1(14)。我有一個正規 表達式找到這些比賽

回答

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) 

更新是,這種解決方案也適用於您的新需求。所有你需要的是爲每個項目生成的密鑰,並更換keyfun的身體與它穩定的方式:

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

你如何生成每個項目的關鍵描述不夠清晰,但是應該用上面的例子可以弄清楚自己。

+0

不錯的解決方案!問題在於它不像「姓氏」那樣簡單(我應該在OP中更清楚地說明)。實際上,我想匹配的字符串並不相同,相反,它們看起來更像這樣:「foo2(bar13)」 - 「foo2(bar14)」。也就是說,如果兩個字符串具有相同的foo id(2),並且如果條形碼id是奇數(13),則其匹配是條形碼id + 1(14)。我有一個正則表達式來查找這些匹配,那麼是否可以擴展您的解決方案以適合我的情況?我不是100%確定我明白groupby是如何工作的。 –