Django ORM — Агрегат от Decorator

Я пытаюсь использовать Django ORM для агрегирования по полю и суммирования значения, возвращаемого декоратором. Я новичок в Django ORM, так что простите меня, если я что-то упустил.

Вот мой класс:

class Payroll(models.Model):
    job = models.ForeignKey(Job, on_delete=models.CASCADE)      
    user = models.ForeignKey(User, on_delete=models.CASCADE)    
    ClockIn = models.DateTimeField()
    ClockOut = models.DateTimeField(null=True, blank=True)

    @property
    def time_worked(self):
        return self.ClockOut - self.ClockIn

Я хочу агрегировать по user и суммировать декоратор time_worked. Если бы я сам писал SQL, это было бы:

SELECT user, SUM(time_worked) 
FROM payroll
GROUP BY user

Когда я пытаюсь

users_time_worked = Payroll.objects.aggregate(Sum('time_worked'))

страница падает, и на экране отладки Django говорится: "Невозможно преобразовать ключевое слово time_worked в поле."

Можно ли суммировать поле timdelta, созданное декоратором с помощью Django ORM? Это то, что я должен вычислить в представлении?

Вы не можете использовать свойство, так как база данных ничего не знает о time_worked. Свойство — это не поле в базе данных, это просто то, что Django/Python будет вычислять при получении .time_worked.

Willem Van Onsem 13.12.2020 22:14

Кроме того, не совсем ясно, что должно произойти, если ClockOut равно NULL/None. Это приведет к ошибке при получении .time_worked.

Willem Van Onsem 13.12.2020 22:21
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
161
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Можно ли суммировать поле timdelta, созданное декоратором с помощью Django ORM? Это то, что я должен вычислить в представлении?

Нет. Свойство не существует на стороне базы данных. База данных ничего не знает о time_worked. Это что-то определенное на уровне Django/Python. Если вы таким образом извлечете .time_worked, Python просто извлечет .ClockOut и .ClockIn и вернет результат вычитания этих двух.

Вам, однако, не нужно time_worked здесь. Вы можете вычесть ClockOut из ClockIn на стороне базы данных:

from django.db.models import DurationField, F, Sum

users_time_worked = Payroll.objects.aggregate(
    total=Sum(F('clockOut') - F('clockIn'), output_field=DurationField())
)['total']

Другие вопросы по теме