#22549 closed Bug (worksforme)
DateTimeField raises timezone awareness related RuntimeWarnings when it should'nt
| Reported by: | Owned by: | nobody | |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | |
| Severity: | Normal | Keywords: | |
| Cc: | matias@… | Triage Stage: | Accepted |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
I've experienced some issues with wrong RuntimeWarnings about naive datetimes being raised when the
datetime I was using was perfectly timezone aware and I think I found the reason why:
In django/db/models/fields/init.py file, inside the definition of DateTimeField.to_python method,
the timezone awareness of a datetime is checked calling the isinstance function.
if isinstance(value, datetime.date):
value = datetime.datetime(value.year, value.month, value.day)
if settings.USE_TZ:
# For backwards compatibility, interpret naive datetimes in
# local time. This won't work during DST change, but we can't
# do much about it, so we let the exceptions percolate up the
# call stack.
warnings.warn("DateTimeField %s.%s received a naive datetime "
"(%s) while time zone support is active." %
(self.model.__name__, self.name, value),
RuntimeWarning)
Is true that, as said here https://docs.python.org/2.7/library/datetime.html#available-types,
"objects of the date type are always naive", but is wrong to use isinstance since all datetime.datetime
objects are also instances of datetime.date because datetime.datetime is a subclass of datetime.date
(which I think is confusing since breakes the OOP intuition that says that class inheritance should
describe "is a" relationships).
A posible solution is to compare using type(value) == datetime.date or, more clearly, check using django.utils.is_naive
Change History (2)
comment:1 by , 12 years ago
| Easy pickings: | unset |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
comment:2 by , 12 years ago
| Resolution: | → worksforme |
|---|---|
| Status: | new → closed |
Look two lines above -- the complete code is:
if isinstance(value, datetime.datetime): return value if isinstance(value, datetime.date): # ... stuff you complain aboutIf
valueis adatetime.datetimethe first branch returns, you don't hit the second branch.