У мене є поле в одній моделі, як:
class Sample(models.Model):
date = fields.DateField(auto_now=False)
Тепер мені потрібно фільтрувати об’єкти за діапазоном дат.
Як я фільтрую всі об'єкти, які мають дату між 1-Jan-2011і 31-Jan-2011?
У мене є поле в одній моделі, як:
class Sample(models.Model):
date = fields.DateField(auto_now=False)
Тепер мені потрібно фільтрувати об’єкти за діапазоном дат.
Як я фільтрую всі об'єкти, які мають дату між 1-Jan-2011і 31-Jan-2011?
Відповіді:
Використовуйте
Sample.objects.filter(date__range=["2011-01-01", "2011-01-31"])
Або якщо ви просто намагаєтесь фільтрувати місяць:
Sample.objects.filter(date__year='2011',
date__month='01')
Як сказав Бернхард Валлант, якщо ви хочете набір запитів, який виключає, specified range endsви повинні розглянути його рішення , яке використовує gt / lt (більше-ніж / менше-ніж).
__rangeвключає межі (як, наприклад, sql BETWEEN), якщо ви не хочете, щоб межі були включені, вам доведеться перейти з моїм рішенням gt / lt ...
order_byнад створеним QuerySetвищезгаданим filter. Я не користувався Джанго роками.
Ви можете використовувати джангоfilter з datetime.dateоб'єктами :
import datetime
samples = Sample.objects.filter(sampledate__gte=datetime.date(2011, 1, 1),
sampledate__lte=datetime.date(2011, 1, 31))
Виконуючи діапазони джанго з фільтром, переконайтеся, що ви знаєте різницю між використанням об’єкта дати та об'єктом дати. __range включається в дати, але якщо ви використовуєте об'єкт datetime для кінцевої дати, він не буде включати записи для цього дня, якщо час не встановлено.
startdate = date.today()
enddate = startdate + timedelta(days=6)
Sample.objects.filter(date__range=[startdate, enddate])
повертає всі записи від початкового до кінця оновлення, включаючи записи в ці дати. Поганий приклад, оскільки це повернення записів на тиждень у майбутнє, але ви отримуєте дрейф.
startdate = datetime.today()
enddate = startdate + timedelta(days=6)
Sample.objects.filter(date__range=[startdate, enddate])
бракує записів на суму 24 години залежно від того, на який час встановлено час для полів дати.
dateоб’єкт: >>> from datetime import date >>> startdate = date.today()
Ви можете обійти "невідповідність імпедансу", викликану недостатньою точністю в 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, а не возитися з викинутими (і плутати) datetimeоб'єктами. Подальше пояснення див. У коментарях нижче.
Example.objects.filter(created__range=[date(2014, 1, 1), date(2014, 2, 1)])не включатимуться об’єкти, створені на date(2014, 2, 1), як @cademan пояснив корисно. Але якщо ви збільшили дату закінчення, додавши один день, ви отримаєте набір запитів, що охоплюють ці відсутні об'єкти (і зручно опускати об'єкти, створені date(2014, 2, 2)через ту саму вигадку). Прикра тут - те, що вказаний діапазон "посібника" created__gte ... created__lte=date(2014, 2, 1)також не працює, що, безумовно, контр-інтуїтивно зрозумілий IMHO.
Це просто,
YourModel.objects.filter(YOUR_DATE_FIELD__date=timezone.now())
Працює для мене
Щоб зробити його більш гнучким, ви можете сконструювати FilterBackend, як показано нижче:
class AnalyticsFilterBackend(generic_filters.BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
predicate = request.query_params # or request.data for POST
if predicate.get('from_date', None) is not None and predicate.get('to_date', None) is not None:
queryset = queryset.filter(your_date__range=(predicate['from_date'], predicate['to_date']))
if predicate.get('from_date', None) is not None and predicate.get('to_date', None) is None:
queryset = queryset.filter(your_date__gte=predicate['from_date'])
if predicate.get('to_date', None) is not None and predicate.get('from_date', None) is None:
queryset = queryset.filter(your_date__lte=predicate['to_date'])
return queryset
Дотепер актуальна і сьогодні. Ви також можете зробити:
import dateutil
import pytz
date = dateutil.parser.parse('02/11/2019').replace(tzinfo=pytz.UTC)