2014-09-04 111 views
1

我想知道哪個是過濾對象的最佳方法,它具有一個外鍵模型的多個參數/值對。 例子:django:通過一個外鍵模型的多個鍵值對來過濾對象

class Car(models.Model): 
    name = models.SlugField("Name") 

class Parameter(models.Model): 
    name = models.SlugField() 
    value = models.TextField(blank=True) 
    car = models.ForeignKey('Car', related_name = 'parameters') 

比方說,我有一些汽車有這3個具體參數:(NAME =顏色,值=藍色); (名稱=輪胎,價值=固特異); (名稱=座位,價值=皮革)

過濾所有具有這些特定參數/值組合的汽車的最佳方法是什麼? 我現在所做的是在一個循環之後過濾一個參數/值對。但這需要很長時間,我相信還有更好的方法。不知何故,通過聚合也許......?

現在唯一的辦法,我得到它的工作是:

Job.objects.filter(Q(parameters__name="tire", parameters__value="Goodyear")).filter(Q(parameters__name="color", parameters__value="blue")).filter(Q(parameters__name="seat", parameters__value="leather")) 

回答

1

如果我理解你正確地你正在尋找或某些查詢過濾器,默認的Django AND將所有過濾器一起。介紹ORing你應該使用Q對象。在您的例子中,你將需要與運算(&)和或門的組合(|):

from django.db.models import Q 

queryset = Car.objects.filter(
    (Q(parameters__name='color') & Q(parameters__value='blue')) | 
    (Q(parameters__name='tire') & Q(parameters__value='Goodyear')) | 
    (Q(parameters__name='seat') & Q(parameters__value='leather')) 
) 

注意從車的反向查找參數。

這應該等於讓我所有的汽車有參數:名稱=顏色和價值=藍色或參數:名稱=輪胎和價值=固特異或參數:名稱=座位和價值=皮革。

+0

不,我需要這些參數的ANDing。我只想讓那些擁有這三個參數的汽車(即可能有沒有參數顏色的汽車等)和2.它們具有給定的值。我已經試過了你用&做的方式,但是這不起作用。 – 2014-09-08 09:17:23

1

使用Q選項。

from django.db.models import Q 

query = Q() 
query &= (Q(name='color') & Q(value='blue')) 
query &= (Q(name='tire') & Q(value="Goodyear")) 
query &= (Q(name="seat") & Q(value="leather")) 

# List : Force the db call to one call 
result = list(Parameters.objects.filter(query)) 
for c in result: 
    c.car 

應該有效。

+0

謝謝你的回答,但我已經處理過這個問題,它不會以這種方式工作。 – 2014-09-08 09:20:01

+0

在你的情況下,唯一的好迴應是你的:一個過濾器鏈。我試過了一個小分貝。 但在你的情況下,也許你應該重新考慮db設計。如果您有兩輛車A和B以及一輛輪胎製造商C,則您的數據庫中將有2 C條目。 請考慮ManyToManyField: [代碼] 類車(models.Model): 名= models.SlugField( 「名稱」) 參數= models.ManyToManyFields( '參數') [/代碼] 它的工作原理。 – 2014-09-08 13:36:08