2013-10-27 93 views
3

我試圖找出是否可能建立一個查詢,其將採取行動像Model.objects.values_list('id', 'related_model__ids')和返回類似[(1L, [2L, 6L]), (2L, [1L,]), (3L, [1L, 3L, 4L, 5L]), ...]這裏的一部分是一些細節:Django的:一個相關的模型值列表作爲值列表查詢

class Player(models.Model): 
    positions = models.ForeignKey(Position) 
    ... 

>>> # players 31, 32, 33 play multiple positions, and I want a result to be 
>>> # [(player.id, [a list of position.id for all positions]), ...] 

>>> Player.objects.filter(id__in=[31, 32, 33]).values_list('id', 'positions__id') 
[(31L, 13L), (31L, 7L), (32L, 13L), (32L, 8L), (33L, 13L), (33L, 7L)] 

這個values_list查詢爲相同的id值產生多個元組,id=31,id=32id=33兩個條目。當我利用特定的球員(id=31)一個values_list查詢,我得到我想要的位置ID列表:

>>> p31 = Player.objects.get(id=31) 
>>> position_ids = p31.positions.values_list('id', flat=True) 
>>> type(position_ids) 
<class 'django.db.models.query.ValuesListQuerySet'> 
>>> position_ids 
[13L, 7L] 
>>> 
>>> # I want [(31L, [13L, 7L]), (32L, [13L, 8L), (33L, [13L, 7L)] 
>>> # Without have to do something like a list comprehension: 
>>> # [(p.id, list(p.positions.values_list('id', flat=True)) 
>>> #  for p in Player.objects.filter(id__in=[31, 32, 33])] 

毫無疑問,一個列表解析會產生的結果,我想。我想避免多個個人查詢到數據庫,每個list(p.positions.values_list('id', flat=True))強制ValuesListQuerySet的分辨率成爲一個實際列表。當然,如果我不強制解決方案,對列表理解結果的操作似乎會執行新的p.positions.valuse_list('id', flat=True)查詢。

回答

3

是的,我希望有一些分組查詢方法。

我最近不得不做一些類似的高度嵌套模型,以避免一些數據庫調用的癱瘓。我最終使用了values()來有效地獲得我需要的所有umm值。然後,將所有東西拼成一個純Python的字典。它結束了數英里更高的效率,但當然定製有其自身的維護下降。

它的要點,用作者/預訂模型:

# models.py 
class Author(models.Model): 
    name = models.CharField() 

class Book(models.Model): 
    name = models.CharField() 
    authors = models.ManyToManyField(Author) 

然後在視圖(或在我的情況下,殼)構建可以傳遞給你的模板字典:

>>> authors = Author.objects.prefetch_related('book_set').values('id', 'book') 
>>> print authors 
    [{'book': 1, 'id': 1}, {'book': 2, 'id': 1}, {'book': 2, 'id': 2}] 
>>> author_dict = {} 
>>> for a in authors: 
    if a['id'] not in author_dict: 
     author_dict[a['id']] = set() 
    author_dict[a['id']].add(a['book']) 
>>> print author_dict 
    {1: set([1, 2]), 2: set([2])} 

不是你可能想要的答案,但它是我唯一想到的。我很想聽聽其他人是否用某種本地Django方法解決了這個問題。

希望這會有所幫助!

+0

你的回答反映了我實際工作的內容。我運行的搜索查詢太多,很難打到數據庫,所以我正在編寫一個模型,它可以保存運行某些查詢及其結果的手段。下一步是找出如何讓自定義模型管理器檢查查詢結果是保存還是需要運行查詢並保存結果。你看過用模型查詢綁定你的字典嗎? – Cole

+1

我沒有。通常,當我不能再使用Django的語法(非SQL語句)優化我的查詢時,是時候將Web服務器從數據庫服務器分離到不同的機器上(無論如何,如果有資源,這是個好主意)。如果可能的話,它可以是更多的硬件或自定義SQL。另外請注意,在某些情況下,使用'prefetch_related'可能比'select_related'快得多。 – Fiver

+1

此外,忘了提及它,但有一個夢幻般的數據庫調試器Django稱爲[django調試工具欄](https://github.com/django-debug-toolbar/django-debug-toolbar)。你可能已經在使用它了,但我想補充說,對於誰停下來。 – Fiver

相關問題