¿Cómo filtro objetos de consulta por rango de fechas en Django?
Tengo un campo en un modelo como:
class Sample(models.Model):
date = fields.DateField(auto_now=False)
Ahora necesito filtrar los objetos por un rango de fechas.
¿Cómo filtro todos los objetos que tienen una fecha entre 1-Jan-2011
y 31-Jan-2011
?
Usar
Sample.objects.filter(date__range=["2011-01-01", "2011-01-31"])
O si simplemente estás intentando filtrar por meses:
Sample.objects.filter(date__year='2011',
date__month='01')
Editar
Como dijo Bernhard Vallant, si desea un conjunto de consultas que excluya, specified range ends
debe considerar su solución , que utiliza gt/lt (mayor que/menor que).
Puedes usar Djangofilter
con datetime.date
objetos :
import datetime
samples = Sample.objects.filter(sampledate__gte=datetime.date(2011, 1, 1),
sampledate__lte=datetime.date(2011, 1, 31))
Cuando haga rangos de Django con un filtro, asegúrese de conocer la diferencia entre usar un objeto de fecha y un objeto de fecha y hora. __range incluye fechas, pero si usa un objeto de fecha y hora para la fecha de finalización, no incluirá las entradas para ese día si no se establece la hora.
from datetime import date, timedelta
startdate = date.today()
enddate = startdate + timedelta(days=6)
Sample.objects.filter(date__range=[startdate, enddate])
devuelve todas las entradas desde la fecha de inicio hasta la fecha de finalización, incluidas las entradas en esas fechas. Mal ejemplo, ya que se trata de devolver entradas dentro de una semana, pero ya entiendes la tendencia.
from datetime import datetime, timedelta
startdate = datetime.today()
enddate = startdate + timedelta(days=6)
Sample.objects.filter(date__range=[startdate, enddate])
Faltarán 24 horas de entradas dependiendo de la hora establecida en los campos de fecha.
Puede solucionar la "falta de coincidencia de impedancia" causada por la falta de precisión en la DateTimeField/date
comparación de objetos (que puede ocurrir si se usa el rango ) usando datetime.timedelta para agregar un día a la última fecha en el rango. Esto funciona como:
start = date(2012, 12, 11)
end = date(2012, 12, 18)
new_end = end + datetime.timedelta(days=1)
ExampleModel.objects.filter(some_datetime_field__range=[start, new_end])
Como se mencionó anteriormente, sin hacer algo como esto, los registros se ignoran el último día.
Editado para evitar el uso de datetime.combine
-- parece más lógico seguir con instancias de fecha cuando se compara con a DateTimeField
, en lugar de jugar con datetime
objetos desechables (y confusos). Vea más explicaciones en los comentarios a continuación.