#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.

Reply via email to