I am trying to filter a DateTimeField comparing with a date. I mean:


I get an empty queryset list as an answer because (I think) I am not considering time, but I want “any time”.

Is there an easy way in Django for doing this?

I have the time in the datetime setted, it is not 00:00.

Such lookups are implemented in django.views.generic.date_based as follows:

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

Because it is quite verbose there are plans to improve the syntax using __date operator. Check “#9596 Comparing a DateTimeField to a date is too hard” for more details.


// edit after comments

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

doest not work because it creates a datetime object with time values set to 0, so the time in database doesn’t match.

Here are the results I got with ipython’s timeit function:

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

1000 loops, best of 3: 631 us per loop

1000 loops, best of 3: 541 us per loop

1000 loops, best of 3: 536 us per loop

contains seems to be faster.

Now Django has __date queryset filter to query datetime objects against dates in development version. Thus, it will be available in 1.9 soon.

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

the above is what I’ve used. Not only does it work, it also has some inherent logical backing.

As of Django 1.9, the way to do this is by using __date on a datetime object.

For example:

This produces the same results as using __year, __month, and __day and seems to work for me:


assuming active_on is a date object, increment it by 1 day then do range

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

You can do like this


or if you want to filter between 2 dates

    datetime_field__date__range=(datetime.date(2009,8,22), datetime.date(2009,9,22))

There’s a fantastic blogpost that covers this here: Comparing Dates and Datetimes in the Django ORM

The best solution posted for Django>1.7,<1.9 is to register a transform:

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.

    def as_sql(self, compiler, connection):
        lhs, params = compiler.compile(self.lhs)
        return 'DATE({})'.format(lhs), params

    def output_field(self):
        return models.DateField()

Then you can use it in your filters like this:



This solution is definitely back end dependent. From the article:

Of course, this implementation relies on your particular flavor of SQL having a DATE() function. MySQL does. So does SQLite. On the other hand, I haven’t worked with PostgreSQL personally, but some googling leads me to believe that it does not have a DATE() function. So an implementation this simple seems like it will necessarily be somewhat backend-dependent.

Here is an interesting technique– I leveraged the startswith procedure as implemented with Django on MySQL to achieve the result of only looking up a datetime through only the date. Basically, when Django does the lookup in the database it has to do a string conversion for the DATETIME MySQL storage object, so you can filter on that, leaving out the timestamp portion of the date– that way %LIKE% matches only the date object and you’ll get every timestamp for the given date.

datetime_filter = datetime(2009, 8, 22) 

This will perform the following query:

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

The LIKE BINARY in this case will match everything for the date, no matter the timestamp. Including values like:

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

Hopefully this helps everyone until Django comes out with a solution!

You can filter by the Date as per as the date format is the same with your django date format. Default format is ISO YYYY-MM-DD

target_date = "2009-08-22"
qs = MyObject.objects.filter(datetime_attr__date=target_date)

Hm.. My solution is working:

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

Model.objects.filter(datetime__year=2011, datetime__month=2, datetime__day=30)

In Django 1.7.6 works:


See the article Django Documentation

ur_data_model.objects.filter(ur_date_field__gte=datetime(2009, 8, 22), ur_date_field__lt=datetime(2009, 8, 23))

person = Profile.objects.get(id=1)

tasks = Task.objects.filter(assigned_to=person, time_stamp__year=person.time_stamp.utcnow().year)

all my model do have time_stamp so I used the person objects to obtain the current year

You can filter between some day ranges

2016-01-01 00:00:00 <--> 2016-04-01 23:59:59.99999

01-01', '%Y-%d-%m'), datetime.min.time()), 
date_joined__lte=datetime.combine(datetime.strptime('2016-04-01', '%Y-%d-%m'), 

2016-01-01 00:00:00 <--> 2016-01-14 00:00:00

User.objects.filter(date_joined__gte="2016-01-01", date_joined__lte="2016-1-14").count()


Just as simple as that if you have a datetimefield your can use datetime.date.today()

context['now'] = Mymodel.objects.filter(date_time_field=datetime.date.today())