138

I am looking to make a query that selects between dates with Django.

I know how to do this with raw SQL pretty easily, but how could this be achieved using the Django ORM?

This is where I want to add the between dates of 30 days in my query:

start_date = datetime.datetime.now() + datetime.timedelta(-30)
context[self.varname] = self.model._default_manager.filter(
    current_issue__isnull=True
    ).live().order_by('-created_at')
Serjik
  • 10,543
  • 8
  • 61
  • 70
Jeff Taggarty
  • 1,391
  • 2
  • 8
  • 4

4 Answers4

279

Use the __range operator:

...filter(current_issue__isnull=True, created_at__range=(start_date, end_date))
suhailvs
  • 20,182
  • 14
  • 100
  • 98
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Is the "created_at" an arbitrary field in a model or is this the databases actual log of when the record was created? – Bigbob556677 Mar 02 '18 at 14:22
  • @Philip556677 It's an arbitrary field in a model. You can set the DateField's [auto_now_add](https://docs.djangoproject.com/en/2.0/ref/models/fields/#django.db.models.DateField.auto_now_add) parameter to True in order to have it easily. – Benbb96 Mar 26 '18 at 13:28
26

__range

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
6

If you are using a DateTimeField, Filtering with dates won’t include items on the last day.

You need to casts the value as date:

...filter(created_at__date__range=(start_date, end_date))
suhailvs
  • 20,182
  • 14
  • 100
  • 98
3

two methods

.filter(created_at__range=[from_date, to_date])

another method

.filter(Q(created_at__gte=from_date)&Q(created_at__lte=to_date))
  • gte means greater than equal
  • lte means less than equal
Manjuanth V M
  • 137
  • 2
  • 9
  • 3
    Q Objects is unnecessary in the second method, you can write: `.filter(created_at__gte=from_date, created_at__lte=to_date)` – Carmoreno Jul 23 '20 at 14:16