#25875: Unicode error when converting a Q object to a string
----------------------------------------------+----------------------------
Reporter: benjaminjkraft | Owner: benjaminjkraft
Type: Bug | Status: new
Component: Database layer (models, ORM) | Version: master
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------------------+----------------------------
If you have a model whose `__str__` returns non-ASCII text, and you refer
to that model in a `Q` object, attempting to `print` that `Q` object, or
otherwise convert it to a string, will error. This is a regression in
Django 1.5, caused indirectly by
[https://github.com/django/django/commit/3dd5d72 3dd5d72], and remains an
issue in master; I believe it should only affect python 2 but I haven't
actually checked.
The issue appears to be that `django.utils.tree.Node.__str__`
inadvertently attempts to convert the string back to unicode. In
particular, since [https://github.com/django/django/commit/3dd5d72
3dd5d72], `self.connector` is a unicode string if `self` is a `Q` object.
This causes python to convert the string being formatted and all its
formatting arguments to unicode. Since this is done implicitly it uses
the default encoding (ASCII), which fails.
Fixing this should be as simple as just explicitly doing
`str(self.connector)` instead, although I haven't yet run the tests to see
if that breaks anything else. In any case, I'm happy to write a patch to
do that later this week. It's possible it would be better to instead
define a `__unicode__` method and avoid the string-conversion entirely,
I'm not sure, but this seems simpler.
Complete repro:
{{{
# in models.py
class Foo(models.Model):
name = models.TextField()
def __unicode__(self):
return u'Foƶ'
def __str__(self):
return unicode(self).encode('utf-8')
def __repr__(self):
return str(self)
# in a shell
Q(baz=Foo(name="baz")) # raises UnicodeDecodeError
}}}
Note that the repro works as long as at least one of `__unicode__`,
`__str__`, and `__repr__` is defined and returns non-ASCII text -- they
don't need to all be explicitly defined.
--
Ticket URL: <https://code.djangoproject.com/ticket/25875>
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 post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/057.8c5d632c344cf497d28790ed0281c79f%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.