Django查询未正确分组

时间:2018-09-22 21:58:48

标签: python django

    class Category(BaseEntity):
        """ to categorise the expense """
        name = models.CharField(
            max_length=80,
            validators=[
                RegexValidator(
                    regex='^[a-zA-Z\s]*$',
                     message='name should contain only alphabets',
                    code='invalid_name'
                ),
            ]
        )
        description = models.CharField(
            max_length=250,
            validators=[
                RegexValidator(
                    regex='^[a-zA-Z\s]*$',
                     message='name should contain only alphabets',
                    code='invalid_name'
                ),
            ],
            null = True,
            blank = True
        )

        parent_category = models.ForeignKey(
                'self',
                related_name = 'child_categories',
                on_delete = models.CASCADE,
                null = True,
                blank = True
        )



class Expense(BaseEntity):
    """covers all the expenses"""

    SEGMENT_CHOICES=(
        ('RENTALS', 'Rentals'),
        ('MIXING', 'Mixing'),
        ('ALBUMS', 'Albums'),
        ('SALES', 'Sales'),
    )

    amount = models.IntegerField(
            default=500,
            validators=[
                MinValueValidator(
                    0,
                    message = 'Amount should be greater than 0'
                ),

                MaxValueValidator(
                    100000,
                    message = 'Amount should be less than 100000'
                ),
            ]
        )
    category = models.ForeignKey(
            'accounting.Category',
            related_name='expenses',
            on_delete=models.CASCADE,
            null = True,
            blank = True
    )

    date = models.DateField(
            verbose_name='spending date'
        )

    description = models.CharField(
        max_length=250,
        validators=[
            RegexValidator(
                regex='^[a-zA-Z\s]*$',
                 message='name should contain only alphabets',
                code='invalid_name'
            ),
        ],
        null = True,
        blank = True
    )
    event = models.ForeignKey(
            'booking.Event',
            related_name='event_expenses',
            blank = True,
            null =True,
            on_delete=models.CASCADE
        )
    business_segment= models.CharField(
        max_length =15,
        choices = SEGMENT_CHOICES,
        default = 'RENTALS',
    )

查询:

expense_category = Expense.objects.values('category__name').annotate(total=Sum('amount'))

输出如下所示:

 <QuerySet [{'category__name': 'Diesel', 'total': 2000}, {'category__name': 'Diesel', 'total': 2000}, {'category__name': 'Diesel', 'total': 2000}, {'category__name': 'Diesel', 'total': 3000}, {'category__name': 'web live', 'total': 1600}, {'category__name': 'Diesel', 'total': 2200}, {'category__name': 'Diesel', 'total': 1000}, {'category__name': 'Diesel', 'total': 1000}, {'category__name': 'Diesel', 'total': 500}, {'category__name': 'Diesel', 'total': 1600}, {'category__name': 'Diesel', 'total': 2500}, {'category__name': 'Bills', 'total': 200}, {'category__name': 'Diesel', 'total': 5600}]>

即使Diesel有许多条目,也无法正确分组。我在查询中缺少任何内容吗?我不喜欢为此做列表处理,我希望通过查询方法来完成。列表逻辑只会使事情复杂化,浪费处理能力

1 个答案:

答案 0 :(得分:1)

注释Category个对象(具有额外的属性)

首先,我认为从Category对象进行查询更有意义,那么也许我们甚至不需要执行适当的分组依据,例如:

Category.objects.annotate(total=Sum('expenses__amount'))

这将导致一个QuerySet,其中每个Category都有一个额外的属性.total。这样做可能更好,因为从那时起您就可以访问Category的所有属性,并且它的行为类似于Category

查询QuerySet的字典

如果只希望使用QuerySet字典,则需要在末尾添加.order_by(..)属性(是的,我知道这听起来很奇怪),例如:

qs = Category.objects.values(
    'name'
).annotate(
    total=Sum('expenses__amount')
).order_by('name')

这将导致:

<QuerySet [
    { 'name': 'bar', 'total': 14.0 }
    { 'name': 'foo', 'total': 25.0 }
]>

但是请注意,如果两个类别具有 same 名称,则它们将加起来,这可能并不理想。