﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
34921	Filtering an unbound DateTimeField with naive date crashes	David Sanders	David Sanders	"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
}}}"	Bug	closed	Database layer (models, ORM)	dev	Normal	fixed			Ready for checkin	1	0	0	0	0	0
