如何在Django模型方法中传入函数运算结果作为参数
问题解决方法
错误原因
你遇到的语法错误是因为 Python 禁止在函数定义的参数列表中直接使用运行时计算的表达式作为参数默认值,timezone.now() + timedelta(days=-2)属于动态执行的计算逻辑,不能直接写在参数声明的位置。
另外补充一个常见的隐藏坑:就算语法允许你把timezone.now()写在参数默认值位置,这个时间也只会在Django启动加载类定义时计算一次,后续所有调用都会复用这个旧时间,完全达不到你要的每次调用取当前时间的效果。
修复代码
你可以把参数默认值设为固定常量None,将动态计算的逻辑移到函数内部处理,同时保留参数的可自定义能力:
from django.utils import timezone from datetime import timedelta from django.db.models import Sum, Q class User(AbstractUser): # 原有字段省略 def get_performance(self, start_date=None, end_date=None): # 仅当没有传入参数时,默认计算最近两天的时间范围 if start_date is None: start_date = timezone.now() + timedelta(days=-2) if end_date is None: end_date = timezone.now() actual = Sum("scores", filter=Q(status="completed")) # 这里直接用处理后的参数,不要重新计算时间,避免参数失效 q = self.taskassignt.filter( due__gte=start_date, due__lt=end_date ).annotate(actual=actual, total=Sum("scores")) # 新增空数据判断,避免没有符合条件的任务时抛出索引错误、或者总分为0时的除零错误 if not q.exists() or q[0].total == 0: return 0 return (q[0].actual / q[0].total) * 100
如果你不需要自定义时间范围,不需要对外开放这两个参数,直接在函数内部计算时间即可,不用定义这两个参数。
内容的提问来源于stack exchange,提问作者Thaddeaus Iorbee
相关产品推荐
相关产品推荐

