Модель Джанго, прошедшая между двумя полями DateTimeFields - PullRequest
0 голосов
/ 13 марта 2019

Я довольно новичок в django и не смог найти способ получить прошедшее время между двумя полями DateTimeFields и сохранить его в другой модели.

from django.db import models



class Timesheet(models.Model):
    startTime = models.DateTimeField(auto_now_add=True)
    endTime = models.DateTimeField(blank=True, null=True)
    duration = models.DateTimeField(endTime - startTime)

    def _str_(self):
        return self.startTime

Как я могу сделать duration = endTime - startTime?Я также использую базу данных PostgreSQL.

Ответы [ 3 ]

1 голос
/ 13 марта 2019

Используйте annotate () для вычисления поля duration во время запроса для каждого объекта в наборе запросов

from django.db.models import F, ExpressionWrapper, fields    

timesheets = Timesheet.objects.annotate(
    duration=ExpressionWrapper(
        F('endTime') - F('startTime'),
        output_field=fields.DurationField()
    )
)

timesheets[0].duration  # datetime.timedelta(0, 722, 18373)

Возможно выполнить другие методы набора запросов над аннотациями, такими как filter(), order_by(), aggregate() и т. Д.

timesheets.order_by('-duration')  
timesheets.aggregate(Avg('duration')) # {'duration__avg': datetime.timedelta(0, 26473, 292625)} 
0 голосов
/ 14 марта 2019
duration = timesheet.end_time - timesheet.start_time

Когда вы вычитаете два экземпляра datetime, вы получаете не другой экземпляр datetime, а timedelta instace, который представляет собой разницу в днях, секундах и микросекундах между двумя datetime. Вы не можете хранить временную дельту в поле DateTime, но вы можете использовать IntegerField, например:

days_in_seconds = duration.days * 86400   # days difference by seconds in a day
duration_in_seconds = duration.seconds + days_in_seconds  # duration in seconds

Если вы хотите получить доступ к продолжительности как к timedelta, просто сделайте:

import datetime

duration = datetime.timedelta(seconds=timesheet.duration)

Вы также можете сохранить его как FloatField, как предложено в этом вопросе .

0 голосов
/ 14 марта 2019

Я бы не использовал выделенное поле модели для продолжительности.

Я бы использовал свойство модели вместо той же функциональности.

Что-то вроде:

@property
def duration(self)
    return self.end_time - self.startime

У Лукаса есть хорошая идея использовать аннотацию, но если у вас есть экземпляр расписания, который не был получен из этого менеджера объектов и ранее не был аннотирован, вам придется сделать отдельное попадание в базу данных, чтобы фактически аннотировать его.

Это свойство используется как таковое:

some_timesheet_instance.duration
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...