2014-09-04 112 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