2010-07-20 57 views
2

)破壞它,過濾器內部所有查詢的表名被重命名爲u0,u1,...。 ..,所以我多餘的where子句將不知道要指向哪個表。我很想不必手動進行所有查詢,以便我可以在這些數據上進行選擇,而我目前的解決方法是將我的額外'd查詢pk values_lists,但這些真的很慢並且是可憎的東西django's .extra(where =子句被表重命名爲.filter(foo__in = ...子查詢

這是所有這些看起來像你可以大多忽略這個管理器方法的額外細節,除了第一個sql指向products_product.id的行:

def by_status(self, *statii): 
    return self.extra(where=["""products_product.id IN                                     
     (SELECT recent.product_id                                           
      FROM (                                               
      SELECT product_id, MAX(start_date) AS latest                                     
      FROM products_productstatus                                          
      GROUP BY product_id                                            
     ) AS recent                                              
      JOIN products_productstatus AS ps ON ps.product_id = recent.product_id                               
      WHERE ps.start_date = recent.latest                                        
      AND ps.status IN (%s))""" % (', '.join([str(stat) for stat in statii]),)]) 

對於僅涉及products_product表的所有情況而言,這非常有效。

當我想將這些產品作爲一個子查詢,我做的:

Piece.objects.filter(
    product__in=Product.objects.filter(
     pk__in=list(
      Product.objects.by_status(FEATURED).values_list('id', flat=True)))) 

我怎樣才能保持一個查詢集的通用能力,並仍然使用一個額外的where子句?

+0

如果不是很明顯,我想看看「Product.objects.filter(pk__in = list(」該解決方案的一部分消失了。 – outofculture 2010-07-20 20:04:03

+0

)您可以發佈您想要在您的應用程序中使用的實際代碼,這個查詢將由django生成(即使它的SQL表命名錯誤)。你可以用'print Piece.objects.filter(...)。query'來完成這個查詢。謝謝! – 2010-07-20 20:18:47

+0

Piece.objects.filter(product__in = Product.objects.by_status(FEATURED)) – outofculture 2010-07-20 21:25:26

回答

3

起初:這個問題對我來說並不完全清楚。您問題中的第二個代碼塊是否是您想要執行的實際代碼?如果是這種情況,查詢應該按預期工作,因爲沒有執行子查詢。

我假設您希望使用第二個代碼塊而不是list(),以避免執行第二個查詢。


django文檔提到了這個問題in the documentation about the extra method。然而,克服這個問題並不是很容易。

最簡單但最「拗口」的解決方案是觀察django爲您想要在額外方法中查詢的表生成哪個表別名。只要您始終以相同的方式構建查詢(您不會更改導致聯接的多個extra方法或filter調用的順序),就可以依賴此別名的持久命名。

您可以檢查一個查詢,將在數據庫中查詢集通過使用執行:

print Model.objects.filter(...).query 

這將揭示用於您要查詢的表的別名。

+0

對,我知道我可以重寫額外的地方根據具體情況使用u0或u1,但我希望能夠給我的模板/視圖人員一個常規的查詢集,這些查詢集的工作方式與我在其他地方提供的查詢集相似。 – outofculture 2010-07-20 21:28:39