Как передать конкатенированные функции в качестве аргумента в методе модели django

Я пытаюсь передать 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, start_time=timezone.now() + timedelta(days=-2), end_time=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:
        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 
    ).annotate(actual=actual, total=Sum("scores"))

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

Однако странно иметь 100 * q[0].actual / q[0].total. Это означает, что вы заинтересованы только в первых taskassignt, а не во всех. Вероятно, вы хотите .aggregate(…) [Django-doc] вместо .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']
Вернуться на верх