在模型上执行Django查询,但是使用该模型的ManyToManyField的QuerySet结束

Performing a Django Query on a Model, But Ending Up with a QuerySet for That Model's ManyToManyField

我有一个第三方django应用程序(satchmo),它有一个名为Product的模型,我在django网站上广泛使用它。

我想增加通过颜色搜索产品的能力。所以我创建了一个新的模型,叫做ProductColor。这个模型大致看起来像这样…

1
2
3
4
5
6
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对象。该计划允许用户通过搜索颜色范围来搜索产品。

我似乎不知道如何将这个查询放入查询集中。我能做到…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 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属性的productsmanytomany属性来构建Product的列表。

我真正需要的是一个有效的Products查询集。这是因为将有其他逻辑对这些结果执行,它需要在QuerySet对象上操作。

所以我的问题是如何构建我真正想要的查询集?如果失败,是否有一种有效的方法来重新构建查询集(最好不要再次访问数据库)?


您可以使用范围字段查找:

You can use range anywhere you can use
BETWEEN in SQL -- for dates, numbers
and even characters.

您的查询:

1
2
3
4
5
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()


如果要获取Product查询集,必须过滤Product对象,并通过产品颜色的反向关系过滤:

埃多克斯1〔2〕