如何在 Django 模型方法中将连接的函数作为参数传递

How to pass concatenated functions as a argument in django model method

我正在尝试将 timezone.now() + timedelta(days=-2)timezone.now() 作为 django 模型方法中的参数传递,但我得到

def performance(user, timezone.now() + timedelta(days=-2), timezone.now()):
                                  ^
SyntaxError: invalid syntax

我知道这个错误是串联的结果,但我不知道如何解决这个问题。

class User(AbstractUser):
    .........................
    fields
    .........................

    def get_performance(self, timezone.now() + timedelta(days=-2), timezone.now()):

        actual = Sum("scores", filter=Q(status="completed"))

        q = self.taskassignt.filter(
            due__gte=timezone.now() + timedelta(days=-2),
            due__lt=timezone.now() 
        ).annotate(actual=actual, total=Sum("scores"))

        return (q[0].actual / q[0].total) * 100

您需要指定一个参数名称,所以

def get_performance(self, <strong>start_time=</strong>timezone.now() + timedelta(days=-2), <strong>end_time=</strong>timezone.now()):
    actual = Sum("scores", filter=Q(status="completed"))
    q = self.taskassignt.filter(
        due__gte=start_time,
        due__lt=end_time 
    ).annotate(actual=actual, total=Sum("scores"))

    return 100 * q[0].actual / q[0].total

但这不起作用,因为默认值将被初始化一次,然后每次都被使用。这意味着如果您的服务器整整一年都是 运行,start_time 仍然是前一年的时间。

通常使用 None 作为默认值,如果参数确实是 None,请将其替换为给定的表达式,因此:

def get_performance(self, start_time=None, end_time=None):
    if start_time is None:
        <strong>start_time = timezone.now() + timedelta(days=-2)</strong>
    if end_time is None:
        <strong>end_time = timezone.now()</strong>
    actual = Sum("scores", filter=Q(status="completed"))
    q = self.taskassignt.filter(
        due__gte=start_time,
        due__lt=end_time 
    ).annotate(actual=actual, total=Sum("scores"))

    return 100 * q[0].actual / q[0].total

但是有一个 100 * q[0].actual / q[0].total 很奇怪。这意味着您只对 firsttaskassignt 感兴趣,而不是全部。您可能想要 .aggregate(…) [Django-doc] instead of .annotate(…) [Django-doc]:

def get_performance(self, start_time=None, end_time=None):
    if start_time is None:
        start_time = timezone.now() + timedelta(days=-2)
    if end_time is None:
        end_time = timezone.now()
    actual = Sum("scores", filter=Q(status='completed'))
    q = self.taskassignt.filter(
        due__gte=start_time,
        due__lt=end_time 
    ).aggregate(actual=actual, total=Sum("scores"))

    return 100 * q['actual'] / q['total']