Django的 - 与组在一对多的关系选择嵌套集合魅力(Django - Select nested

2019-09-29 23:59发布

我有以下型号,什么我想是基于通过review_question_id组选择的企业的集合,他们每个人的AVG(率)的集合。

这里有必要的机型:

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的任何帮助,将不胜感激。

Answer 1:

如果你使用Django的休息框架会容易。 你应该使用两个串行。

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')


文章来源: Django - Select nested collection Avg with group by in one to many relationship