Найти объекты с датой и временем менее чем через 24 часа

У меня есть модель с двумя полями:

class Event(models.Model):
    date = models.DateField(_(u'Date'))
    time = models.TimeField(_(u'Time'))

Мне нужно найти все объекты, где дата и время будут через 24 часа.

Я могу сделать это при использовании поля DateTime, но я не уверен, как это сделать, когда поля разделены. Спасибо заранее.

Ответ 1

Для простого случая (не уверен, что все это простые случаи, хотя...), это должно сделать трюк:

import datetime

today = datetime.datetime.now()
tomorrow = today + datetime.timedelta(days=1)

qs_today = queryset.filter(
    date=today.date(),
    time__gte=today.time(),
)
qs_tomorrow = queryset.filter(
    date=tomorrow.date(),
    time__lt=tomorrow.time(),
)
qs = qs_today | qs_tomorrow

Ответ 2

Как вы заявляете, вы можете делать то, что хотите, с помощью DateTimeField, но теперь с отдельными полями, я понимаю, что ваша проблема заключается в том, как их объединить.

Глядя на документы для DateField - ваша переменная date является экземпляром datetime.date и аналогично для TimeField time - это datetime.time. Вы можете преобразовать их в datetime.datetime, используя combine()

import datetime as dt
datetime = dt.datetime.combine(date,time)

Теперь у вас есть объект datetime, как и у DateTimeField. Вы говорите в вопросе, который вы можете сделать через 24 часа оттуда, хотя дайте мне знать в комментариях, если вам это нужно, чтобы сделать явным.

Caveat я combine не удастся, если одно из полей None - вы заявляете, что этого не может быть, поэтому я не добавил никаких проверок ошибок или проверки этого.

ИЗМЕНИТЬ

Мне кажется, что проблема может быть не комбинацией, а добавлением вычисленного поля к объекту Event. Вы можете посмотреть этот Q & A или этот. В итоге вы определяете вычисленное значение в функции в своем классе, а затем создаете property - либо с помощью декоратора или вызова функции, Там пример в документах, адаптирующийся для вашего случая:

    def _get_datetime(self):
       '''Returns a combination of date and time as a datetime'''
       return dt.datetime.combine(self.date,self.time)
    datetime = property(_get_datetime)

Это должно вести себя так же, как вы ожидали бы от DateTimeField.

Ответ 3

Вы можете использовать объекты Q для поиска "вчера после текущего времени или сегодня до текущего времени":

from django.db.models import Q
from .models import Event
from datetime import datetime, timedelta

def get_event_during_last_day():
    now = datetime.now()
    today = now.date()
    yesterday = (now - timedelta(day=1)).date()
    time = now.time()

    query_yesterday = Q(date=yesterday, time__gt=time)
    query_today = Q(date=today, time__lt=time)

    return Event.objects.filter(query_yesterday | query_today)