Eventos de filtro Django que ocurren hoy

Estoy luchando para representar lógicamente lo siguiente en un filtro Django. Tengo un modelo de ‘evento’ y un modelo de ubicación, que se puede representar como:

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() 

Para una ubicación determinada, quiero seleccionar todos los eventos que ocurren hoy. He intentado varias estrategias a través del método ‘bookings_today’ en el EventManager, pero la syntax de filtro correcta me elude:

 class EventManager(models.Manager): def bookings_today(self, location_id): bookings = self.filter(location=location_id, start=?, end=?) 

La fecha () falla, ya que esto reduce a cero los tiempos, y el tiempo durante el día es crítico para la aplicación, lo mismo ocurre con el mínimo y máximo de las fechas, y su uso como final de cuentas. Además, existen múltiples configuraciones válidas posibles:

 start_date < today, end_date during today start_date during today, end_date during today start_date during today, end_date after today 

¿Debo codificar todo un conjunto de opciones diferentes o hay un método más simple y elegante?

Necesitará dos umbrales de datetime y datetime distintos: today_start y 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()) 

Cualquier cosa que suceda hoy debe haber comenzado antes de today_end y finalizado después de today_start , así que:

 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) 

(PS: tener un DateTimeField (no un DateField ) llamado foo_date es irritantemente engañoso; considere simplemente start y end …)

Necesitas usar un rango como este:

 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 

Ninguna de las respuestas que vi es consciente de la zona horaria.

¿Por qué no haces esto?

 from django.utils import timezone class EventManager(models.Manager): def bookings_today(self, location_id): bookings = self.filter(location=location_id, start__gte=timezone.now().replace(hour=0, minute=0, second=0), end__lte=timezone.now().replace(hour=23, minute=59, second=59)) 

¿Qué tal esto: pub_date__gte=datetime(2005, 1, 1) ? Utilice _gte y __lte para limitar el inicio y el final en un día utilizando el método de encadenamiento.

Tal vez algo como self.filter(start__gte=datetime(2005, 1, 1)).filter(end__lte=datetime(2005, 1, 1)) . lte significa menor o igual que, gte significa mayor o igual que.

Lo encuentro en django doc .

Creo que excluir es tu amigo aquí!

 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 ) 

timezone.localtime(timezone.now()).date() da la fecha correcta.

Para que los eventos ocurran hoy ( start hoy):

 from django.utils import timezone class EventManager(models.Manager): def bookings_today(self, location_id): t = timezone.localtime(timezone.now()) bookings = self.filter(location=location_id, start__year = t.year, start__month = t.month, start__day = t.day, )