It doesn't work because a datetime has more pieces than year, month, day, and if you do an exact lookup with two datetimes that differ in the parts you don't care about, they aren't going to come out as matching simply because you didn't specify values for the pieces you are not interested in. Those values are going to get set to something, I'd guess zero. If that's not what the values are for the "matching" entries in the DB, than an exact lookup won't find them.
See:
(InteractiveConsole)
>>> from dttest.models import Twd
>>> import datetime
>>> twd = Twd(date=datetime.datetime.today())
>>> twd.save()
>>> twd = Twd.objects.all()[0]
>>> twd
<Twd: 2008-09-05 19:40:44>
>>> x = Twd.objects.filter(date=datetime.datetime(2008,9,5))[0]
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/kmt/tmp/django/trunk/django/db/models/query.py", line 232, in __getitem__
return list(qs)[0]
IndexError: list index out of range
>>> from django.db import connection
>>> connection.queries[-1]
{'time': '0.001', 'sql': u'SELECT `dttest_twd`.`id`, `dttest_twd`.`date` FROM `dttest_twd` WHERE `dttest_twd`.`date` = 2008-09-05 00:00:00 LIMIT 1'}
The matching-day object wasn't found because it doesn't match on the hh:mm:ss field. startswith can be made to work, but you have to make sure to pass in just a date, not a full datetime for the comparison. If you pass in a full datetime, you'll still be trying to match on 0's for the time. In fact on MySQL you'll get an error:
>>> x = Twd.objects.filter(date__startswith=datetime.datetime(2008,9,5))[0]
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/kmt/tmp/django/trunk/django/db/models/query.py", line 232, in __getitem__
return list(qs)[0]
File "/home/kmt/tmp/django/trunk/django/db/models/query.py", line 156, in __len__
self._result_cache.extend(list(self._iter))
File "/home/kmt/tmp/django/trunk/django/db/models/query.py", line 269, in iterator
for row in self.query.results_iter():
File "/home/kmt/tmp/django/trunk/django/db/models/sql/query.py", line 206, in results_iter
for rows in self.execute_sql(MULTI):
File "/home/kmt/tmp/django/trunk/django/db/models/sql/query.py", line 1700, in execute_sql
cursor.execute(sql, params)
File "/home/kmt/tmp/django/trunk/django/db/backends/util.py", line 19, in execute
return self.cursor.execute(sql, params)
File "/home/kmt/tmp/django/trunk/django/db/backends/mysql/base.py", line 83, in execute
return self.cursor.execute(query, args)
File "/var/lib/python-support/python2.5/MySQLdb/cursors.py", line 168, in execute
if not self._defer_warnings: self._warning_check()
File "/var/lib/python-support/python2.5/MySQLdb/cursors.py", line 82, in _warning_check
warn(w[-1], self.Warning, 3)
File "warnings.py", line 62, in warn
globals)
File "warnings.py", line 102, in warn_explicit
raise message
Warning: Incorrect datetime value: '2008-09-05 00:00:00%' for column 'date' at row 1
>>> connection.queries[-1]
{'time': '0.002', 'sql': u'SELECT `dttest_twd`.`id`, `dttest_twd`.`date` FROM `dttest_twd` WHERE `dttest_twd`.`date` LIKE BINARY 2008-09-05 00:00:00% LIMIT 1'}
because apparently MySQL doesn't like the % in that query to be placed beyond (or within) the seconds part of the datetime. But if you pass in just a date:
>>> x = Twd.objects.filter(date__startswith=datetime.date(2008,9,5))[0]
>>> x
<Twd: 2008-09-05 19:40:44>
>>> connection.queries[-1]
{'time': '0.001', 'sql': u'SELECT `dttest_twd`.`id`, `dttest_twd`.`date` FROM `dttest_twd` WHERE `dttest_twd`.`date` LIKE BINARY 2008-09-05% LIMIT 1'}
>>>
you get the result you are looking for. (These startswith results may be database-dependent, though, I haven't tried on anything other than MySQL.)
Karen