我正在编写一个管理命令,它会根据建议的价格过滤产品的原始价格。
我的产品型号如下:
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的两个字段?查询中的模型?
答案 0 :(得分:10)
from django.db.models import F
Product.objects.filter(price__in=F('suggestions'))
答案 1 :(得分: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
,假设我们 in 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
可能会更快,我不确定,但无论如何,你最终会得到一份价格相同的产品和建议清单。