【发布时间】:2018-12-30 20:53:22
【问题描述】:
有没有办法在数据库 annotate 调用中将 F() 表达式传递给函数,例如 dateutil 的 relativedelta。
鉴于以下情况,InterestLoan.objects.active_loans(start_date='2018-01-01', end_date='2019-01-01') 将返回一个查询集 a给定期限内的活跃贷款。 end_date 需要使用 start_date + term注释。
相反,我得到 TypeError: bad operand type for unary +: 'F'
class InterestLoanSet(models.QuerySet):
def add_end_date(self):
return self.annotate(loan_end_date=ExpressionWrapper(F('start_date') + relativedelta(months=+F('term'), output_field=DateField())))
def active_loans(self, start_date, end_date):
return self.exclude(start_date__gt=end_date).add_end_date().exclude(loan_end_date__lt=start_date)
class InterestLoan(AbstractTransaction):
objects = InterestLoanSet.as_manager()
interest_nominal_code = models.ForeignKey(NominalCode, null=False, on_delete=models.PROTECT)
balance_nominal_code = models.ForeignKey(NominalCode, null=False, on_delete=models.PROTECT, related_name='loans')
principal = models.DecimalField(max_digits=10, decimal_places=2)
term = models.PositiveIntegerField()
interest_rate = models.DecimalField(max_digits=4, decimal_places=4)
【问题讨论】:
-
它对
relativedelta(month=+F('term'), ...)中的+进行了比较。 -
删除 '+' 会产生不同的错误:TypeError: int() 参数必须是字符串、类似字节的对象或数字,而不是 'F' @WillemVanOnsem
-
这是不可能的,因为表达式的全部意义在于它是在数据库中完成的。您将需要找到可以转换为 SQL 的等价物。
标签: django python-3.x django-queryset django-annotate