События фильтра Django, происходящие сегодня
Я пытаюсь логически представить следующее в фильтре Django. У меня есть модель "события" и модель местоположения, которая может быть представлена как:
class Location(models.Model):
name = models.CharField(max_length=255)
class Event(models.Model):
start_date = models.DateTimeField()
end_date = models.DateTimeField()
location = models.ForeignKeyField(Location)
objects = EventManager()
Для данного местоположения я хочу выбрать все события, происходящие сегодня. Я пробовал различные стратегии с помощью метода bookings_today в EventManager, но правильный синтаксис фильтра ускользает от меня:
class EventManager(models.Manager):
def bookings_today(self, location_id):
bookings = self.filter(location=location_id, start=?, end=?)
date() терпит неудачу, поскольку это обнуляет время, а время в течение дня имеет решающее значение для приложения, то же самое относится к минимальным и максимальным датам и использует их в качестве книг. Кроме того, существует несколько возможных допустимых конфигураций:
start_date < today, end_date during today
start_date during today, end_date during today
start_date during today, end_date after today
Нужно ли мне кодировать целый набор различных параметров или есть более простой и элегантный метод?
Ответы
Ответ 1
Вам понадобятся два разных порога datetime
- today_start
и today_end
:
from datetime import datetime, timedelta, time
today = datetime.now().date()
tomorrow = today + timedelta(1)
today_start = datetime.combine(today, time())
today_end = datetime.combine(tomorrow, time())
Все, что происходит сегодня, должно начаться до того, как today_end
и закончилось после today_start
, поэтому:
class EventManager(models.Manager):
def bookings_today(self, location_id):
# Construction of today_end / today_start as above, omitted for brevity
return self.filter(location=location_id, start__lte=today_end, end__gte=today_start)
(P.S. Имея a DateTimeField
(не a DateField
), называемый foo_date
, вызывает раздражение - рассмотрите только start
и end
...)
Ответ 2
Вам нужно использовать такой диапазон:
class EventManager(models.Manager):
def bookings_today(self, location_id):
from datetime import datetime
now = datetime.now()
bookings = self.filter(location=location_id, start__lte=now, end__gte=now)
return bookings
Ответ 3
Как насчет этого: pub_date__gte=datetime(2005, 1, 1)
? Используйте _gte
и __lte
, чтобы ограничить начало и конец в течение одного дня с помощью метода цепочки.
Возможно, что-то вроде self.filter(start__gte=datetime(2005, 1, 1)).filter(end__lte=datetime(2005, 1, 1))
. lte
означает меньшее или равное, gte
означает больше или равно.
Я нахожу его в django doc.
Ответ 4
Я думаю, что исключаю твой друг здесь!
today = datetime.date.today()
tomorrow = today + datetime.timedelta( days = 1 )
self.filter( location = location_id ).exclude( end_date__lt = today ).exclude( start_date__gte = tomorrow )