2011-03-24 69 views
1

我有一個第三方Django應用程序(Satchmo),其中有一個模型叫Product,我在我的Django站點廣泛使用。在模型上執行Django查詢,但結束與該模型的ManyToManyField QuerySet

我想添加通過顏色搜索產品的功能。所以我創建了一個名爲ProductColor的新模型。這款機型的外觀大致是這樣的......

class ProductColor(models.Model): 
    products = models.ManyToManyField(Product) 
    r = models.IntegerField() 
    g = models.IntegerField() 
    b = models.IntegerField() 
    name = models.CharField(max_length=32) 

當商店產品的數據加載到該網站,該產品的顏色數據被用來創建一個ProductColor對象將指向Product object.The計劃是允許用戶通過搜索顏色範圍來搜索產品。

我似乎無法弄清楚如何把這個查詢放入QuerySet中。我可以做這個...

# If the color ranges look something like this... 
r_range, g_range, b_range = ((3,130),(0,255),(0,255)) 

# Then my query looks like 
colors_in_range = ProductColor.objects.select_related('products') 
if r_range: 
    colors_in_range = colors_in_range.filter(
     Q(r__gte=r_range[0]) 
     | Q(r__lte=r_range[1]) 
    ) 
if g_range: 
    colors_in_range = colors_in_range.filter(
     Q(g__gte=g_range[0]) 
     | Q(g__lte=g_range[1]) 
    ) 
if b_range: 
    colors_in_range = colors_in_range.filter(
     Q(b__gte=b_range[0]) 
     | Q(b__lte=b_range[1]) 
    ) 

所以我結束了它包含了所有在該顏色範圍ProductColor對象的查詢集。然後,我可以通過訪問ProductColor屬性的products ManyToMany屬性來構建Product的列表。

我真正需要的是Product個有效的查詢集。這是因爲在這些結果上會執行其他邏輯,並且它需要在QuerySet對象上運行。

所以我的問題是如何構建我真正想要的QuerySet?如果失敗了,是否有一種有效的方式重新構建QuerySet(最好不要再次訪問數據庫)?

回答

1

如果你想獲得一個Product查詢集,你必須過濾Product對象,並通過對產品的顏色相反的關係進行過濾:

products = Product.objects.filter(productcolor_set__r__gte=x).distinct()

+0

是否即使'productcolor'上沒有'Product'模型中定義的所有這些工作?我在哪裏可以閱讀該功能的文檔? – 2011-03-25 00:05:43

+0

我想我找到了它:http://docs.djangoproject.com/en/dev/topics/db/queries/#related-objects – 2011-03-25 00:09:20

+0

反向關係是由django自動創建的。如果你比'productcolor_set'更喜歡別的名字,定義例如。 'ManyToManyField'的定義上'related_name ='productcolors'! – 2011-03-25 00:13:46

1

可以使用range現場查詢:

您可以使用範圍的任何地方,你可以在SQL中使用 之間 - 的日期,數字 甚至字符。

查詢:

r_range, g_range, b_range = ((3,130),(0,255),(0,255)) 

products = Product.objects.filter(productcolor_set__r__range=r_range, 
    productcolor_set__g__range=g_range, 
    productcolor_set__b__range=b_range).distinct() 
+0

謝謝!這也是很好的信息。 – 2011-03-25 02:05:33

+0

是否有效的過濾器語法?它不應該是'.filter(productcolor_set__r__range = r_range,productcolor_set__g__range = g_range,productcolor_set__b__range = b_range)'? – 2011-03-25 19:55:24

+0

哦,你是絕對正確的...... = P不知道爲什麼我試圖通過作爲參數範圍...固定! – DTing 2011-03-25 22:07:40