如何比较查询中模型的两个字段?

时间:2021-07-08 01:29:49

I'm writing a management command which will filter a product's original price with suggested prices.

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

I have a product model which looks like :

我有一个产品型号,看起来像:

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

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

I want to filter all products whose price is equal to minumum suggestion. Something should like :

我想过滤所有价格等于最低建议的产品。有点像:

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

AND

I want to filter products where the suggestions contains the Product's original price. Something should like :

我想过滤建议中包含产品原价的产品。有点像:

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

The problem is I can't use a for-loop to look each Product's minumum suggestion and as you guess I can't use object's self either, so how can I compare two fields of a model in a query ?

问题是我不能使用for循环查看每个产品的最小建议,因为你猜我也不能使用对象的自我,那么如何在查询中比较模型的两个字段?

2 个解决方案

#1


9  

from django.db.models import F
Product.objects.filter(price__in=F('suggestions'))

#2


2  

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

suggestions is not a field on Product (and the columns passed to F should have quotes, like F('suggestions') not F(suggestions)). So that's no good.

建议不是产品上的字段(传递给F的列应该有引号,如F('建议')而不是F(建议))。所以这不好。

The raw SQL for this is something like this, which joins onto a subquery that gets the minimum price for every product, then filters the list down to those products whose price == the min price.

原始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

You cannot perform (as of 1.4) a custom join in this way using the django ORM. You will need to use a raw SQL query.

您无法使用django ORM以这种方式执行(自1.4开始)自定义连接。您将需要使用原始SQL查询。

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

self.suggestions, assuming we are in a Product instance method, is not a list, so far it's a RelatedSetManager. I doubt, though, that you want to get all the products that have one of the suggested prices of the current (aka self) product. That seems odd.

self.suggestions,假设我们在Product实例方法中,不是列表,到目前为止它是一个RelatedSetManager。不过,我怀疑你想获得所有具有当前(又称自我)产品价格之一的产品。这看起来很奇怪。

What it sounds like you want is a list of products that have a suggestion that matches one of the suggested prices.

你想要的是一个产品清单,其中的建议与建议的价格之一相匹配。

You'll need raw SQL again. :-/

你需要再次使用原始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

That would do it, I think. RIGHT JOIN might be faster there, I'm not sure, but anyway you'd end up with a list of products and suggestions that have the same price.

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

#1


9  

from django.db.models import F
Product.objects.filter(price__in=F('suggestions'))

#2


2  

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

suggestions is not a field on Product (and the columns passed to F should have quotes, like F('suggestions') not F(suggestions)). So that's no good.

建议不是产品上的字段(传递给F的列应该有引号,如F('建议')而不是F(建议))。所以这不好。

The raw SQL for this is something like this, which joins onto a subquery that gets the minimum price for every product, then filters the list down to those products whose price == the min price.

原始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

You cannot perform (as of 1.4) a custom join in this way using the django ORM. You will need to use a raw SQL query.

您无法使用django ORM以这种方式执行(自1.4开始)自定义连接。您将需要使用原始SQL查询。

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

self.suggestions, assuming we are in a Product instance method, is not a list, so far it's a RelatedSetManager. I doubt, though, that you want to get all the products that have one of the suggested prices of the current (aka self) product. That seems odd.

self.suggestions,假设我们在Product实例方法中,不是列表,到目前为止它是一个RelatedSetManager。不过,我怀疑你想获得所有具有当前(又称自我)产品价格之一的产品。这看起来很奇怪。

What it sounds like you want is a list of products that have a suggestion that matches one of the suggested prices.

你想要的是一个产品清单,其中的建议与建议的价格之一相匹配。

You'll need raw SQL again. :-/

你需要再次使用原始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

That would do it, I think. RIGHT JOIN might be faster there, I'm not sure, but anyway you'd end up with a list of products and suggestions that have the same price.

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