Как передать конкатенированные функции в качестве аргумента в методе модели 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']