diff --git a/django/utils/encoding.py b/django/utils/encoding.py index eb60cfde8bd61..7030ab1db01e4 100644 --- a/django/utils/encoding.py +++ b/django/utils/encoding.py @@ -39,6 +39,19 @@ def __str__(self): def __str__(self): return self.__unicode__().encode('utf-8') +def python_2_unicode_compatible(klass): + """ + A decorator that defines __unicode__ and __str__ methods under Python 2. + Under Python 3 it does nothing. + + To support Python 2 and 3 with a single code base, define a __str__ method + returning text and apply this decorator to the class. + """ + if not six.PY3: + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + return klass + def smart_text(s, encoding='utf-8', strings_only=False, errors='strict'): """ Returns a text object representing 's' -- unicode on Python 2 and str on diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt index b6cb1035d3d08..97643c29e9981 100644 --- a/docs/ref/utils.txt +++ b/docs/ref/utils.txt @@ -187,6 +187,14 @@ The functions defined in this module share the following properties: Useful as a mix-in. If you support Python 2 and 3 with a single code base, you can inherit this mix-in and just define ``__unicode__``. +.. function:: python_2_unicode_compatible + + A decorator that defines ``__unicode__`` and ``__str__`` methods under + Python 2. Under Python 3 it does nothing. + + To support Python 2 and 3 with a single code base, define a ``__str__`` + method returning text and apply this decorator to the class. + .. function:: smart_text(s, encoding='utf-8', strings_only=False, errors='strict') .. versionadded:: 1.5