2013-11-22 76 views
0

因此QuerySet s是「懶惰」,只能在某些情況下運行(repr,list等)。我創建了一個自定義QuerySet做許多查詢,但這些可能會有數百萬個項目! 這是比我想返回更多的方式。Django自定義QuerySet評估

當返回評估QuerySet時,它不應該有超過25個結果!現在我知道我可以做到以下幾點:

first = example.objects.filter(...) 
last = first.filter(...) 
result = last[:25] 
#do stuff with result 

,但我會用example對象,我覺得沒有必要也行result = last[:25]做這麼多的疑問。 有沒有辦法指定QuerySet返回的方式?

如果有,我怎樣才能改變它,以便每當QuerySet將評估它只返回在QuerySet第一x項目,其中,在這種情況下,x = 25

重要提示:

切片必須在評估,因爲這樣我可以鏈接查詢沒有有限的結果,但是當我評估時返回結果,它將有一個最大值x

回答

1

我不確定我是否理解您在切片查詢集時遇到的問題。如果它的代碼或困擾着你的硬編碼數多餘線,您可以運行

example.objects.filter(**filters)[:x] 

,並通過X爲你使用任何方法。

+0

這是額外的代碼行,我知道我可以使用'x',我只是覺得它沒有必要,因爲它會被調用很多次,比如數千次,而且我無法爲每個自定義過濾器執行它,因爲切片會評估它然後你將無法鏈接 –

+0

文檔說:「通常,切片QuerySet返回一個新的QuerySet - 它不評估查詢。」所以我會說你的答案是要走的路。 – XORcist

+0

@möter「一般情況下」,有時會出現這樣的情況,時間非常重要,我不能冒險評估。此外,這是一個API,它會破壞API –

1

您可以編寫自定義Manager

class LimitedNumberOfResultsManager(models.Manager): 
    def get_queryset(self): 
     return super(LimitedNumberOfResultsManager, self).get_queryset()[:25] 

注:您可能會認爲這裏加上片會立即評估查詢集。它不會。相反,有關查詢限制的信息將保存到底層的Query對象中,並在稍後的最終評估期間使用 - 只要在此期間不會被另一個片段覆蓋。

那麼管理者添加到模型:

class YourModel(models.Model): 
    # ... 

    objects = LimitedNumberOfResultsManager() 

設置此功能YourModel.objects.all()和您的查詢集等操作將始終返回僅達25個結果之後。您仍然可以使用切片覆蓋此任何時間。例如:

這將返回多達25個resuls:

YourModel.objects.filter(lorem='ipsum') 

,但是這將返回多達100個resuls:

YourModel.objects.filter(lorem='ipsum')[:100] 

還有一點。覆蓋默認管理器可能會讓其他人閱讀您的代碼時感到困惑。因此,我認爲這將是更好獨自離開默認管理和使用自定義一個作爲選裝配置:

class YourModel(models.Model): 
    # ... 

    objects = models.Manager() 
    limited = LimitedNumberOfResultsManager() 

有了這個設置,這將返回所有結果:

YourModel.objects.all() 

,這將最多隻能返回25項結果:

YourModel.limited.all() 

根據您的具體使用情況,你斯人也想看看pagination in Django