1

У меня есть модель Booking, которая имеет start и end поля datetime. Я хочу знать, сколько дней занимает бронирование. Я могу сделать это в Python, но мне нужно это значение для дальнейших аннотаций.Как аннотировать разницу между датой и временем в днях

Вот что я пробовал:

In [1]: Booking.objects.annotate(days=F('end')-F('start'))[0].days 
Out[1]: datetime.timedelta(16, 50400) 

Есть несколько проблем здесь:

  • Я хочу, чтобы целое число (или другой тип номера можно использовать в расчетах) дней, как выход, а не timedelta. Установка output_field здесь не имеет смысла.
  • Мои суммы поступили в продажу раз. Вычитания, подобные этому, без удаления времени могут привести к отключению всего количества дней.

В Python я бы сделал (end.date() - start.date()).days + 1. Как я могу сделать это в базе данных, желательно через ORM (например, функции базы данных), но достаточно было бы получить RawSQL, чтобы получить это от двери?

ответ

4

Я написал несколько функций базы данных, чтобы отбрасывать и урезать даты для решения обеих проблем в PostgreSQL. Внутренняя функция DATE_PART и DATE_TRUNC Я использую это DB-специфические ☹

from django.db.models import Func 

class DiffDays(Func): 
    function = 'DATE_PART' 
    template = "%(function)s('day', %(expressions)s)" 

class CastDate(Func): 
    function = 'date_trunc' 
    template = "%(function)s('day', %(expressions)s)" 

Тогда я могу:

In [25]: Booking.objects.annotate(days=DiffDays(CastDate(F('end'))-CastDate(F('start'))) + 1)[0].days 
Out[25]: 18.0 
1

Существует еще одно, простое решение этой проблемы. Вы можете использовать:

from django.db.models import F 
from django.db.models.functions import ExtractDay 

, а затем:

Booking.objects.annotate(days=(ExtractDay(F('end')-F('start'))+1))[0].days 

 Смежные вопросы

  • Нет связанных вопросов^_^