Запрос базы данных Django: как фильтровать объекты по диапазону дат?

У меня есть поле в одной модели, как

class Sample(models.Model):
    date = fields.DateField(auto_now=False)

теперь мне нужно отфильтровать объекты по диапазону данных, например, все объекты, которые имеют дату с 1 января 2011 по 31 января 2011?

Спасибо за вашу помощь!

5 ответов


использовать

Sample.objects.filter(date__range=["2011-01-01", "2011-01-31"])

или если вы просто пытаетесь фильтровать месяц мудрый:

Sample.objects.filter(date__year='2011', 
                      date__month='01')

редактировать

как сказал Бернхард Валлант, если вы хотите queryset, который исключает specified range ends следует считать решение, в котором используется gt/lt (больше/меньше).


можно использовать Джанго!--1--> С datetime.date объекты:

import datetime
samples = Sample.objects.filter(sampledate__gte=datetime.date(2011, 1, 1),
                                sampledate__lte=datetime.date(2011, 1, 31))

при выполнении диапазонов django с фильтром убедитесь, что вы знаете разницу между использованием объекта date и объекта datetime. __range включает даты, но если вы используете объект datetime для даты окончания, он не будет включать записи за этот день, если время не установлено.

    startdate = date.today()
    enddate = startdate + timedelta(days=6)
    Sample.objects.filter(date__range=[startdate, enddate])

возвращает все записи из startdate в enddate, включая записи в эти даты. Плохой пример, так как это возвращает записи на неделю в будущее, но вы получаете дрейф.

    startdate = datetime.today()
    enddate = startdate + timedelta(days=6)
    Sample.objects.filter(date__range=[startdate, enddate])

будет отсутствовать 24 часа записей в зависимости от того, какое время для полей даты установлено.


вы можете обойти "несоответствие импеданса", вызванное отсутствием точности в DateTimeField/date сравнение объектов -- это может произойти при использовании ряд -- С помощью datetime.timedelta чтобы добавить день к последней дате в диапазоне. Это работает так:

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

как обсуждалось ранее, не делая ничего подобного, записи игнорируются в последний день.

отредактировано, чтобы избежать использования datetime.combine -- Кажется более логичным придерживаться даты примеры при сравнении с DateTimeField, вместо того, чтобы возиться с throwaway (и запутанным) datetime объекты. См. дополнительные пояснения в комментариях ниже.


прост,

YourModel.objects.filter(YOUR_DATE_FIELD__date=timezone.now())

для меня