【问题标题】:How can I compare two fields of a model in a query?如何在查询中比较模型的两个字段?
【发布时间】:2011-08-14 00:22:52
【问题描述】:

我正在编写一个管理命令,它将使用建议价格过滤产品的原始价格。

我有一个看起来像这样的产品模型:

class Suggestion(models.Model):
    ....
    price = models.IntegerField()

class Product(models.Model):
    price = models.IntegerField()
    suggestions = models.ManyToManyField(Suggestion)

我想过滤价格等于最低建议的所有产品。应该喜欢的东西:

Product.objects.filter(price = minumum(suggestions))

我想过滤建议中包含产品原价的产品。应该喜欢的东西:

Product.objects.filter(price__in = self.suggestions)

问题是我不能使用 for 循环来查看每个产品的最小建议,而且你猜我也不能使用对象的 self,所以我如何比较 a 的两个字段查询中的模型?

【问题讨论】:

    标签: django filter compare aggregate-functions


    【解决方案1】:
    from django.db.models import F
    Product.objects.filter(price__in=F('suggestions'))
    

    【讨论】:

    • 谢谢!这很好用。然而,有一个小错误:建议必须在 F('suggestions') 内的引号中。
    • 两个F怎么样?例如两个带注释的字段?
    【解决方案2】:
    • Product.objects.filter(price = minumum(suggestions))

    suggestions 不是 Product 上的字段(传递给 F 的列应该有引号,例如 F('suggestions') 而不是 F(suggestions))。所以这不好。

    用于此的原始 SQL 是这样的,它加入一个子查询,获取每个产品的最低价格,然后将列表过滤到价格 == 最低价格的那些产品。

    SELECT * FROM product
      LEFT JOIN (
         SELECT _products_suggestions.product_id, MIN(price) as min_price
         FROM suggestion
         RIGHT JOIN _products_suggestions
         GROUP BY _products_suggestions.product_id
         ) AS min_suggestions ON min_suggestions.product_id = product.id
      WHERE product.price = min_suggestions.price
    

    您不能使用 django ORM 以这种方式执行(从 1.4 开始)自定义连接。您需要使用raw SQL query

    • Product.objects.filter(price__in = self.suggestions)

    self.suggestions,假设我们一个Product实例方法,不是一个列表,到目前为止它是一个RelatedSetManager。不过,我怀疑您是否想获得所有具有当前(又名self)产品的建议价格之一的产品。这似乎很奇怪。

    听起来您想要的是一个产品列表,其建议与建议价格中的一个相匹配。

    您将再次需要原始 SQL。 :-/

    SELECT * FROM product
      LEFT JOIN _products_suggestions ON _products_suggestions.product_id = product.id
      LEFT JOIN suggestion ON _products_suggestions.suggestion_id = suggestion.id
      WHERE suggestion.price = product.price
    

    我想这样就可以了。 RIGHT JOIN 可能会更快,我不确定,但无论如何你最终会得到一个价格相同的产品和建议列表。

    【讨论】:

      猜你喜欢
      • 2021-01-02
      • 1970-01-01
      • 2017-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多