Как сделать группирование по другому атрибуту и ​​суммирование по другому атрибуту в Django? - PullRequest
0 голосов
/ 02 января 2019

models.py:

class Student(models.Model):
    total_fees = models.PositiveIntegerField(blank=False)
    roll_number = models.PositiveIntegerField(blank=False)

class StudentTransaction(models.Model):
    student = models.ForeignKey(Student, on_delete=models.CASCADE, blank=False)
    amount = models.PositiveIntegerField(blank=False)
    timestamp = models.DateTimeField(auto_now_add=True, blank=True)

admin.py:

class StudentTransactionModelAdmin(admin.ModelAdmin):
    list_display = ['__str__', 'time', 'amount']

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'student':
            x = StudentTransaction.objects.order_by().annotate(Sum('amount')).filter(amount__sum__lt=student__total_fees)
            kwargs["queryset"] = [i.student for i in x]
        return super().formfield_for_foreignkey(db_field, request, **kwargs)

При выполнении annotate я хочу получить сумму всех транзакций для каждого учащегося в функции formfield_for_foreignkey. Я хочу фактические Student объекты, так что это не может быть сделано с помощью values.

Чтобы упростить задачу, учтите, что существует 3 Student объектов. Один из них совершил 2 транзакции, другой совершил 4 транзакции, а третий не совершил никаких транзакций. Сумма суммы транзакции на одного студента не превышает total_fees студента. formfield_for_foreignkey должен вернуть все Student объекты тем, кто еще не оплатил их сборы. Состояние:

sum(<all transactions of each student>) is less than <total_fees of that student>

Примечание. Некоторые детали намеренно удалены, чтобы сделать код максимально коротким. Если что-то отсутствует или приведет к ошибке, сообщите об этом.

Ответы [ 2 ]

0 голосов
/ 02 января 2019

Этот запрос должен помочь вам

StudentTransaction.objects.annotate(Sum('amount')).values('student').filter(amount__sum__lte=total_fees)

0 голосов
/ 02 января 2019

Насколько вам нужно вернуть Students, но не StudentTransaction, вы можете сделать это:

students = Student.objects.annotate(transactions_sum=Sum('studenttransaction__amount')).filter(transactions_sum__lt=total_fees)

Если поместить код в ваш метод, он будет выглядеть так:

def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'student':
            students = Student.objects.annotate(transactions_sum=Sum('studenttransaction__amount')).filter(transactions_sum__lt=total_fees)
            kwargs["queryset"] = students
        return super().formfield_for_foreignkey(db_field, request, **kwargs)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...