Django - 以一对多关系选择嵌套集合平均值与分组
Posted
技术标签:
【中文标题】Django - 以一对多关系选择嵌套集合平均值与分组【英文标题】:Django - Select nested collection Avg with group by in one to many relationship 【发布时间】:2018-09-10 06:13:40 【问题描述】:我有以下模型,我想要选择一个业务集合,每个业务都有一个基于 group by review_question_id 的 AVG(rate) 集合。
以下是必要的模型:
class ReviewQuestion(models.Model):
"""Represents a question to be given in a business type
"""
business_type = models.ForeignKey(BusinessType, on_delete=models.CASCADE)
question_text = models.CharField(max_length=100)
class Business(models.Model):
"""Values for a specific business, based on a type
will inherit questions and reviews
"""
business_type = models.ForeignKey(BusinessType, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
class CustomerReview(models.Model):
"""Rate value by customers on a specific quesiton
for a specific business
"""
business = models.ForeignKey(Business, on_delete=models.CASCADE)
review_question = models.ForeignKey(
ReviewQuestion, on_delete=models.CASCADE)
review_value = models.PositiveSmallIntegerField()
我试图接近的最近的查询:
items = Business.objects.filter(business_type_id=type_id).values(
'id', 'name', 'business_type_id', 'address', 'customerreview__review_question_id').annotate(rate=Avg('customerreview__review_value'))
它的问题是重复。它复制了整个列表,结果是扁平的,就像你用扁平 tsql 编写它时得到的一样。
理想的结果应该是这样的:
[
"business_id": 1,
"business_name": "something",
"rating":[
"Question_1":
"title":"ReviewQuestion__question_text",
"Avg":5.0
,
"Question_2":
"title":"ReviewQuestion__question_text",
"Avg":5.0
,
...
]
]
如果我是 python/django 的新手,我将不胜感激。
【问题讨论】:
【参考方案1】:如果你使用 django-rest-framework 会很容易。 您应该使用两个序列化程序。
from rest_framework import serializers
class BussnessSerializer(serializers.ModelSerializer):
rating = QuestionWithRatingSerializer(
source='reviewquestion_set',
many=True
)
business_id = serializers.IntegerField(source='id')
business_name = serizlizers.CharField(source='name')
class Meta:
model = Business
fields = ('rating', 'business_id', 'business_name')
class QuestionWithRatingSerializer(serializers.ModelSerializer):
title = serializers.CharField(source='question_text')
avg = serizlizers.SerializerMethodField()
def get_avg(self, obj):
return obj.customerreview_set.aggregave(
avg=Avg('review_value')['avg'])
class Meta:
model = ReviewQuestion
fields = ('title', 'avg')
【讨论】:
您好,感谢您的回复,因为我说我是新来的。这应该是某种 ViewModel(例如 c# linq viewModels)还是我应该更改我的模型以匹配它? 啊,不。我关注的是来自 docs.djangoproject.com 的文档,而不是来自 rest-framework 的文档.. 如果你愿意,你可以在你的 django 项目中使用 django-rest-framework(django-rest-framework.org)以上是关于Django - 以一对多关系选择嵌套集合平均值与分组的主要内容,如果未能解决你的问题,请参考以下文章