#34921: Filtering an unbound DateTimeField with naive date crashes
-------------------------------------+-------------------------------------
Reporter: David | Owner: nobody
Sanders |
Type: Bug | Status: new
Component: Database | Version: dev
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
It's possible to crash the naive datetime warning in
`DateTimeField.to_python()` by filtering an unbound datetime with a naive
timstamp:
{{{
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
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/34921>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/0107018b562aabe6-b5efa904-e94f-479b-8d49-3fc53240b222-000000%40eu-central-1.amazonses.com.