Fixed #19362 -- Detected invalid use of @python_2_unicode_compatible.

Thanks m3wolf for the report and akaariai for reproducing the problem.
This commit is contained in:
Aymeric Augustin 2012-11-27 09:45:37 +01:00
parent 29d59a879e
commit 2ea80b94d7
3 changed files with 24 additions and 1 deletions

View File

@ -416,6 +416,11 @@ class Model(six.with_metaclass(ModelBase, object)):
def __str__(self): def __str__(self):
if not six.PY3 and hasattr(self, '__unicode__'): if not six.PY3 and hasattr(self, '__unicode__'):
if type(self).__unicode__ == Model.__str__:
klass_name = type(self).__name__
raise RuntimeError("%s.__unicode__ is aliased to __str__. Did"
" you apply @python_2_unicode_compatible"
" without defining __str__?" % klass_name)
return force_text(self).encode('utf-8') return force_text(self).encode('utf-8')
return '%s object' % self.__class__.__name__ return '%s object' % self.__class__.__name__

View File

@ -27,6 +27,14 @@ class Article(models.Model):
# in ASCII. # in ASCII.
return self.headline return self.headline
@python_2_unicode_compatible
class BrokenArticle(models.Model):
headline = models.CharField(max_length=100)
pub_date = models.DateTimeField()
def __unicode__(self): # instead of __str__
return self.headline
@python_2_unicode_compatible @python_2_unicode_compatible
class InternationalArticle(models.Model): class InternationalArticle(models.Model):
headline = models.CharField(max_length=100) headline = models.CharField(max_length=100)

View File

@ -7,7 +7,7 @@ from django.test import TestCase
from django.utils import six from django.utils import six
from django.utils.unittest import skipIf from django.utils.unittest import skipIf
from .models import Article, InternationalArticle from .models import Article, BrokenArticle, InternationalArticle
class SimpleTests(TestCase): class SimpleTests(TestCase):
@ -21,6 +21,16 @@ class SimpleTests(TestCase):
self.assertEqual(str(a), str('Area man programs in Python')) self.assertEqual(str(a), str('Area man programs in Python'))
self.assertEqual(repr(a), str('<Article: Area man programs in Python>')) self.assertEqual(repr(a), str('<Article: Area man programs in Python>'))
@skipIf(six.PY3, "tests Model's default __str__ method under Python 2")
def test_broken(self):
# Regression test for #19362.
a = BrokenArticle.objects.create(
headline='Girl wins €12.500 in lottery',
pub_date=datetime.datetime(2005, 7, 28)
)
self.assertRaisesRegexp(RuntimeError, "Did you apply "
"@python_2_unicode_compatible without defining __str__\?", str, a)
def test_international(self): def test_international(self):
a = InternationalArticle.objects.create( a = InternationalArticle.objects.create(
headline='Girl wins €12.500 in lottery', headline='Girl wins €12.500 in lottery',