【问题标题】:Django - Select nested collection Avg with group by in one to many relationshipDjango - 以一对多关系选择嵌套集合平均值与分组
【发布时间】: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 的新手,我将不胜感激。

【问题讨论】:

    标签: python django python-3.x django-queryset django-orm


    【解决方案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)
    猜你喜欢
    • 2021-12-19
    • 1970-01-01
    • 2021-07-27
    • 1970-01-01
    • 1970-01-01
    • 2022-06-17
    • 2013-03-26
    • 2011-10-21
    • 1970-01-01
    相关资源
    最近更新 更多