Python Django:如何连接和注释多个sql表?
我正在构建一个示例django应用程序,无法正确聚合一些sql结果 考虑以下3种模式: 电影模型 评级模型 注释模型Python Django:如何连接和注释多个sql表?,python,django,django-orm,Python,Django,Django Orm,我正在构建一个示例django应用程序,无法正确聚合一些sql结果 考虑以下3种模式: 电影模型 评级模型 注释模型 然后考虑下面的MySQL表: 电影 +------+------+ |来源_id |标题| +------+------+ |15sdfsd4 |蜘蛛侠| +------+------+ 评级 +--+----+-----+-----+ |id |评级|用户名|电影| id| +--+----+-----+-----+ |1 | 4 |千斤顶| 15sdfsd4| |2 | 3
然后考虑下面的MySQL表:
电影 +------+------+ |来源_id |标题| +------+------+ |15sdfsd4 |蜘蛛侠| +------+------+ 评级 +--+----+-----+-----+ |id |评级|用户名|电影| id| +--+----+-----+-----+ |1 | 4 |千斤顶| 15sdfsd4| |2 | 3 |米克| 15sdfsd4| +--+----+-----+-----+ 评论 +--+-----+----------+-----+ |id |用户名|正文|电影| id| +--+-----+----------+-----+ |1 |查尔斯|我喜欢这部电影| 15sdfsd4| |2 |米克|美妙音效| 15sdfsd4| +--+-----+----------+-----+ 我想查询电影ID列表,并获得平均评级和评论数量的摘要 我试过类似的东西ids = ['15sdfsd4','54fdf5d']
m = Movie.objects.filter(source_id__in=ids).annotate(Avg('rating'), Count('comment'))
对于id为15sdfsd4的电影,我预计评论数为2,平均评级为3.5。相反,我得到的评论数为4,平均评分为1.5,这让我无法理解
你有什么建议吗?谢谢以下解决方案有两个问题 您没有指定要在评级时平均的列 Django结合了多个注释和 考虑到计数聚合具有不同的属性,且重复的平均值相同,这可能会起作用
m = Movie.objects.filter(source_id__in=ids).annotate(
Avg('rating__rating'),
Count('comment',distinct=True)
)
嗨,Crash,请尝试:Movie.objects.annotateavg_rating=Avg'rating_set__all',com_count=count'comment_set_all'或Movie.objects.all.annotateavg_rating=Avg'rating_set_all',com_count count'comment_set_all'Hi@iklinac,通过使用Avg'rating_rating'我得到django.core.exceptions.FieldError:无法将关键字'rating_rating'解析到字段中。选择是:评论,评级,来源id,标题,错误消失时只使用平均'评级'。无论如何,只有计数给出正确的结果2,而平均值给出2.0000。这是由于您在回答中指出的错误造成的吗?@crash double下划线rating\uuuu rating,是的,请查看提供的文档链接。再次感谢@iklinac它使用双下划线工作,您能告诉我它使用Avg'rating'与Avg'rating\uu rating'做了什么吗?@crash with rating它在Avg上的平均idtry也是不同的
class Comment(models.Model):
movie = models.ForeignKey(Movie, on_delete=models.CASCADE)
username = models.CharField(max_length=100, validators=[MinLengthValidator(1)])
body = models.TextField()
ids = ['15sdfsd4','54fdf5d']
m = Movie.objects.filter(source_id__in=ids).annotate(Avg('rating'), Count('comment'))
m = Movie.objects.filter(source_id__in=ids).annotate(
Avg('rating__rating'),
Count('comment',distinct=True)
)