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>
注意:故意删除了一些细节,以使代码尽可能短。如果缺少某些东西或将产生错误,请进行报告。
答案 0 :(得分:1)
只要您需要返回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)
答案 1 :(得分:0)
此查询应为您提供帮助
StudentTransaction.objects.annotate(Sum('amount')).values('student').filter(amount__sum__lte=total_fees)