¿Cómo puedo filtrar una fecha de un DateTimeField en Django?

Estoy tratando de filtrar un DateTimeField comparando con una fecha. Quiero decir:

 MyObject.objects.filter(datetime_attr=datetime.date(2009,8,22)) 

Obtengo una lista de consultas vacía como respuesta porque (creo) no estoy considerando el tiempo, pero quiero “en cualquier momento”.

¿Hay una manera fácil en Django para hacer esto?

Tengo el tiempo en el datetime establecido, no es 00:00 .

Estas búsquedas se implementan en django.views.generic.date_based siguiente manera:

 {'date_time_field__range': (datetime.datetime.combine(date, datetime.time.min), datetime.datetime.combine(date, datetime.time.max))} 

Debido a que es bastante detallado, hay planes para mejorar la syntax utilizando el operador __date . Marque ” # 9596 Comparar un DateTimeField con una fecha es demasiado difícil ” para obtener más detalles.

 YourModel.objects.filter(datetime_published__year='2008', datetime_published__month='03', datetime_published__day='27') 

// editar después de los comentarios

 YourModel.objects.filter(datetime_published=datetime(2008, 03, 27)) 

no funciona porque crea un objeto de fecha y hora con valores de tiempo establecidos en 0, por lo que el tiempo en la base de datos no coincide.

Aquí están los resultados que obtuve con la función timeit de ipython:

 from datetime import date today = date.today() timeit[Model.objects.filter(date_created__year=today.year, date_created__month=today.month, date_created__day=today.day)] 1000 loops, best of 3: 652 us per loop timeit[Model.objects.filter(date_created__gte=today)] 1000 loops, best of 3: 631 us per loop timeit[Model.objects.filter(date_created__startswith=today)] 1000 loops, best of 3: 541 us per loop timeit[Model.objects.filter(date_created__contains=today)] 1000 loops, best of 3: 536 us per loop 

Contiene parece ser más rápido.

 Mymodel.objects.filter(date_time_field__contains=datetime.date(1986, 7, 28)) 

Lo anterior es lo que he usado. No solo funciona, sino que también tiene un respaldo lógico inherente.

Ahora Django tiene __fechas en el filtro de consultas para consultar objetos de fecha y hora con fechas en la versión de desarrollo. Por lo tanto, estará disponible en 1.9 próximamente.

Esto produce los mismos resultados que usar __year, __month y __day y parece funcionar para mí:

 YourModel.objects.filter(your_datetime_field__startswith=datetime.date(2009,8,22)) 

A partir de Django 1.9, la forma de hacerlo es usar __date en un objeto de fecha y hora.

Por ejemplo: MyObject.objects.filter(datetime_attr__date=datetime.date(2009,8,22))

asumiendo que active_on es un objeto de fecha, incrementarlo en 1 día y luego hacer rango

 next_day = active_on + datetime.timedelta(1) queryset = queryset.filter(date_created__range=(active_on, next_day) ) 

Aquí hay una técnica interesante: Aproveché el inicio con el procedimiento implementado con Django en MySQL para lograr el resultado de solo buscar una fecha y fecha hasta la fecha. Básicamente, cuando Django realiza la búsqueda en la base de datos, tiene que hacer una conversión de cadena para el objeto de almacenamiento DATETIME MySQL, para que pueda filtrar en eso, omitiendo la parte de la fecha de la marca de tiempo, de esa manera% LIKE% coincide solo con la fecha objeto y obtendrá cada marca de tiempo para la fecha dada.

 datetime_filter = datetime(2009, 8, 22) MyObject.objects.filter(datetime_attr__startswith=datetime_filter.date()) 

Esto realizará la siguiente consulta:

 SELECT (values) FROM myapp_my_object \ WHERE myapp_my_object.datetime_attr LIKE BINARY 2009-08-22% 

El LIKE BINARY en este caso coincidirá con todo para la fecha, sin importar la marca de tiempo. Incluyendo valores como:

 +---------------------+ | datetime_attr | +---------------------+ | 2009-08-22 11:05:08 | +---------------------+ 

¡Ojalá esto ayude a todos hasta que Django salga con una solución!

Hm .. Mi solución está funcionando:

 Mymodel.objects.filter(date_time_field__startswith=datetime.datetime(1986, 7, 28)) 

Ver el artículo Documentación Django.

Es muy similar a la respuesta de JZ.

 ur_data_model.objects.filter(ur_date_field=datetime(2005, 7, 27) 
 Model.objects.filter(datetime__year=2011, datetime__month=2, datetime__day=30) 

En Django 1.7.6 funciona:

 MyObject.objects.filter(datetime_attr__startswith=datetime.date(2009,8,22)) 

Hay una entrada fantástica de blog que cubre esto aquí: Comparación de fechas y fechas en el ORM de Django

La mejor solución publicada para Django> 1.7, <1.9 es registrar una transformación:

 from django.db import models class MySQLDatetimeDate(models.Transform): """ This implements a custom SQL lookup when using `__date` with datetimes. To enable filtering on datetimes that fall on a given date, import this transform and register it with the DateTimeField. """ lookup_name = 'date' def as_sql(self, compiler, connection): lhs, params = compiler.compile(self.lhs) return 'DATE({})'.format(lhs), params @property def output_field(self): return models.DateField() 

Entonces puedes usarlo en tus filtros así:

 Foo.objects.filter(created_on__date=date) 

EDITAR

Esta solución es definitivamente dependiente de back-end. Del artículo:

Por supuesto, esta implementación se basa en su particular sabor de SQL con una función DATE (). MySQL hace. Lo mismo ocurre con SQLite. Por otro lado, no he trabajado con PostgreSQL personalmente, pero algunas búsquedas en Google me llevan a creer que no tiene una función DATE (). Por lo tanto, una implementación tan simple parece que será necesariamente algo dependiente del backend.