class Review(models.Model):
slug = models.SlugField(max_length=255, unique=True)
vendor = models.ForeignKey(Vendor)
user = models.ForeignKey(User, blank=True, null=True)
product = models.ForeignKey(Product, blank=True, null=True)
images = models.ManyToManyField(ReviewImage, blank=True, null=True)
headline = models.CharField(max_length=100)
review = models.TextField(blank=True, null=True)
rating = models.IntegerField()
active = models.BooleanField(default=1)
created = models.DateTimeField(auto_now_add=True)
changed = models.DateTimeField(auto_now=True)
# This is the problem... I works, but no vendor is shown if there is no review.
vendor_list = (Vendor.objects.filter(category=category,
review__product__isnull=True,
active=True)
.annotate(rating_avg=Avg('review__rating')))
我如何使用review__product__isnull=True
执行此操作?如果根本没有评论,我仍然想要供应商,但评级应该是:“0”,...该怎么办?
答案 0 :(得分:1)
让我们看看我是否理解这一点。您正尝试列出该类别中的所有活跃供应商,并使用其评论的平均评分进行注释。您确定审核是供应商审核而非产品审核的方式是产品字段为空。并且您希望没有评论的供应商的平均评分为零。
在SQL中,您的查询需要OUTER JOIN
:
SELECT vendor.id, COALESCE(AVG(review.rating), 0.0) AS rating
FROM myapp_vendor AS vendor
LEFT OUTER JOIN myapp_review AS review
ON review.vendor_id = vendor.id
AND review.product IS NULL
WHERE vendor.category = %s
AND vendor.active
GROUP BY vendor.id
有时在Django中,最简单的解决方案是raw SQL query:正如开发人员所说,数据库API是“a shortcut but not necessarily an end-all-be-all.”所以看起来像这样:
for v in Vendor.objects.raw('SELECT ... ', [category]): # query as above
print 'Vendor {0} has rating {1}'.format(v.name, v.rating)
答案 1 :(得分:0)
你可以试试这个:
vendor_list = Vendor.objects.filter(category=category, active=True)
vendor_list = vendor_list.filter(Q(review__product__isnull=True)|Q(review__isnull=True)).annotate(rating_avg=Avg('review__rating'))
(过滤器已分为2行,以便于阅读,但可以合并)
这个想法是你首先接受所有供应商,然后筛选那些没有产品评论或根本没有评论的人。然后你注释那些。
缺少审核的供应商的评级为“无”而非“0”。