#34921 closed Bug (fixed)
Filtering an unbound DateTimeField with naive date crashes
| Reported by: | David Sanders | Owned by: | David Sanders |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Ready for checkin | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description (last modified by )
It's possible to crash the naive datetime warning in DateTimeField.to_python() by filtering an unbound datetime with a naive date:
class EmptyModel(Model):
pass
EmptyModel.objects.annotate(unbound=Now()).filter(unbound__gte=date(2000, 1, 1))
The resulting exception is pasted below.
The cause is the unsuccessful access of attribute self.model in DateTimeField.to_python():
warnings.warn(
"DateTimeField %s.%s received a naive datetime "
"(%s) while time zone support is active."
% (self.model.__name__, self.name, value),
RuntimeWarning,
)
DateTime.get_prep_value() handles this correctly by catching the attribute error raised and using the name "unbound" instead:
try:
name = "%s.%s" % (self.model.__name__, self.name)
except AttributeError:
name = "(unbound)"
warnings.warn(
"DateTimeField %s received a naive datetime (%s)"
" while time zone support is active." % (name, value),
RuntimeWarning,
)
Exception details:
path/to/django/db/models/query.py:1476: in filter
return self._filter_or_exclude(False, args, kwargs)
path/to/django/db/models/query.py:1494: in _filter_or_exclude
clone._filter_or_exclude_inplace(negate, args, kwargs)
path/to/django/db/models/query.py:1501: in _filter_or_exclude_inplace
self._query.add_q(Q(*args, **kwargs))
path/to/django/db/models/sql/query.py:1599: in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
path/to/django/db/models/sql/query.py:1631: in _add_q
child_clause, needed_inner = self.build_filter(
path/to/django/db/models/sql/query.py:1499: in build_filter
condition = self.build_lookup(lookups, reffed_expression, value)
path/to/django/db/models/sql/query.py:1375: in build_lookup
lookup = lookup_class(lhs, rhs)
path/to/django/db/models/lookups.py:30: in __init__
self.rhs = self.get_prep_lookup()
path/to/django/db/models/lookups.py:88: in get_prep_lookup
return self.lhs.output_field.get_prep_value(self.rhs)
path/to/django/db/models/fields/__init__.py:1648: in get_prep_value
value = super().get_prep_value(value)
path/to/django/db/models/fields/__init__.py:1527: in get_prep_value
return self.to_python(value)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <django.db.models.fields.DateTimeField>, value = datetime.datetime(2000, 1, 1, 0, 0)
def to_python(self, value):
if value is None:
return value
if isinstance(value, datetime.datetime):
return value
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,
)
E AttributeError: 'DateTimeField' object has no attribute 'model'
path/to/django/db/models/fields/__init__.py:1601: AttributeError
Change History (6)
comment:1 by , 2 years ago
comment:2 by , 2 years ago
| Description: | modified (diff) |
|---|
comment:3 by , 2 years ago
| Has patch: | set |
|---|---|
| Owner: | changed from to |
| Status: | new → assigned |
| Triage Stage: | Unreviewed → Accepted |
Thanks for the report.
comment:4 by , 2 years ago
| Triage Stage: | Accepted → Ready for checkin |
|---|
Note:
See TracTickets
for help on using tickets.
PR to make warning same as
get_prep_value(): https://github.com/django/django/pull/17399