gpt4 book ai didi

Django 在属性字段上进行注释

转载 作者:行者123 更新时间:2023-12-02 03:29:40 25 4
gpt4 key购买 nike

我正在使用 Django 2.0Django REST Framework

我有一个如下所示的模型。

class Contact(models.Model):
first_name = models.CharField(max_length=100)

class AmountGiven(models.Model):
contact = models.ForeignKey(Contact, on_delete=models.PROTECT)
amount = models.FloatField(help_text='Amount given to the contact')

@property
def total_payable(self):
return self.amount

@property
def amount_due(self):
returned_amount = 0
for returned in self.amountreturned_set.all():
returned_amount += returned.amount

return self.total_payable - returned_amount

class AmountReturned(models.Model):
amount_given = models.ForeignKey(AmountGiven, on_delete=models.CASCADE)
amount = models.FloadField()

我必须分别获取给定金额到期的前 10 位联系人。

在我看来,我正在过滤这样的数据

@api_view(http_method_names=['GET'])
def top_ten(request):
filter_type = request.query_params.get('type', None)

if filter_type == 'due':
# query for due type

elif filter_type == 'given':
qs = Contact.objects.filter(
user=request.user
).values('id').annotate(
amount_given=Sum('amountgiven__amount')
).order_by(
'-amount_given'
)[:10]

graph_data = []
for q in qs:
d = {}
contact = Contact.objects.get(pk=q['id'])

d['contact'] = contact.full_name if contact else 'Unknown'
d['value'] = q['amount_given']
graph_data.append(d)

return Response(graph_data)

else:
raise NotFound('No data found for given filter type')

类型查询可以是duegiven

给定类型的代码工作正常,因为所有字段都在数据库中。但是如何根据 due 类型的虚拟字段进行过滤?

我要做的就是按contactamount_due属性组进行注释Sum

最佳答案

您无法根据 @property 进行过滤.

据我正确理解您的问题,您可以汇总相关 AmountGiven 的总和和 AmountReturned 的总和,然后计算due保存字母和前者相减结果的字段。

查询:

from django.db.models import Sum, Value
from django.db.models.functions import Coalesce

Contact.objects.filter(
amountgiven__amount__gt=0
).annotate(
due=Sum('amountgiven__amount') - Coalesce(Sum('amountgiven__amountreturned__amount'), Value(0))
).order_by('-due').values_list('due', 'id')

将返回:

<QuerySet [{'id': 3, 'due': 2500.0}, {'id': 1, 'due': 2450.0}, {'id': 2, 'due': 1500.0}]>

但是,使用此解决方案,您无法区分许多 AmountGiven跨越一Contact 。您会得到像结果一样的大局。

如果您想按 AmountGiven 拆分到期值实例只是像这样注释:

AmountGiven.objects.annotate(
due=Sum('amount') - Coalesce(Sum('amountreturned__amount'), Value(0))
).order_by('-due').values_list('due', 'contact__id', 'id')

返回

<QuerySet [
{'contact__id': 3, 'id': 3, 'due': 2500.0},
{'contact__id': 1, 'id': 1, 'due': 1750.0},
{'contact__id': 2, 'id': 2, 'due': 1500.0},
{'contact__id': 1, 'id': 4, 'due': 350.0},
{'contact__id': 1, 'id': 5, 'due': 350.0}
]>

引用文献

  1. Coalesce

关于Django 在属性字段上进行注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52173340/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com