【问题标题】:Performing a Django Query on a Model, But Ending Up with a QuerySet for That Model's ManyToManyField在模型上执行 Django 查询,但以该模型的 ManyToManyField 的 QuerySet 结束
【发布时间】:2011-07-22 13:29:39
【问题描述】:

我有一个第三方 Django 应用程序 (Satchmo),它有一个名为 Product 的模型,我在我的 Django 站点中广泛使用它。

我想添加通过颜色搜索产品的功能。所以我创建了一个名为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 对象。计划是允许用户通过以下方式搜索产品搜索颜色范围。

我似乎无法弄清楚如何将此查询放入 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])
    )

所以我最终得到了一个 QuerySet,其中包含该颜色范围内的所有 ProductColor 对象。然后我可以通过访问每个ProductColor 属性的products ManyToMany 属性来构建Products 的列表。

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

所以我的问题是如何构建我真正想要的 QuerySet?如果做不到这一点,是否有一种有效的方法来重新构建 QuerySet(最好不要再次访问数据库)?

【问题讨论】:

    标签: django django-queryset satchmo


    【解决方案1】:

    如果您想获得 Product 查询集,您必须过滤 Product 对象并通过产品颜色的反向关系进行过滤:

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

    【讨论】:

    • 即使productcolor 根本没有在Product 模型上定义,这是否有效?我在哪里可以阅读此功能的文档?
    • 反向关系由 django 自己自动创建。如果您更喜欢 productcolor_set 以外的其他名称,请定义例如。 related_name='productcolors关于ManyToManyField的定义!
    • 谢谢!这正是我所需要的。
    • 默认情况下,查询时为Product.objects.filter(productcolor__r__gte=x)。实例方法默认为productcolor_set
    【解决方案2】:

    您可以使用range 字段查找:

    您可以在任何可以使用的地方使用范围 SQL 中的 BETWEEN -- 用于日期、数字 甚至是字符。

    您的查询:

    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()
    

    【讨论】:

    • 谢谢!这也是很棒的信息。
    • 那是有效的过滤器语法吗?不应该是.filter(productcolor_set__r__range=r_range,productcolor_set__g__range=g_range,productcolor_set__b__range=b_range)吗?
    • 哦,你是绝对正确的...... =P不知道为什么我试图将范围作为参数传递......修复!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    • 2014-04-25
    • 2014-01-13
    • 2011-04-18
    • 1970-01-01
    • 2012-07-04
    相关资源
    最近更新 更多