Using __str__() method in Django on Python 2

14,297

Solution 1

To keep the code compatible between py2 and py3, a better way is to use the decorator python_2_unicode_compatible. This way you can keep the str method:

from django.db import models
from django.utils.encoding import python_2_unicode_compatible

@python_2_unicode_compatible
class Question(models.Model):
# ...
    def __str__(self):              # __unicode__ on Python 2
        return self.question_text

@python_2_unicode_compatible
class Choice(models.Model):
# ...
    def __str__(self):              # __unicode__ on Python 2
        return self.choice_text

Reference: https://docs.djangoproject.com/en/1.8/topics/python3/#str-and-unicode-methods

Django provides a simple way to define str() and unicode() methods that work on Python 2 and 3: you must define a str() method returning text and to apply the python_2_unicode_compatible() decorator.

...

This technique is the best match for Django’s porting philosophy.

Solution 2

Yes you can, you just replace __str__ with __unicode__, as the comment states:

class Question(models.Model):
# ...
    def __unicode__(self):
        return self.question_text

class Choice(models.Model):
# ...
    def __unicode__(self):
        return self.choice_text

Further down that section you'll find a bit of explanation:

__str__ or __unicode__?

On Python 3, it’s easy, just use __str__().

On Python 2, you should define __unicode__() methods returning unicode values instead. Django models have a default __str__() method that calls __unicode__() and converts the result to a UTF-8 bytestring. This means that unicode(p) will return a Unicode string, and str(p) will return a bytestring, with characters encoded as UTF-8. Python does the opposite: object has a __unicode__ method that calls __str__ and interprets the result as an ASCII bytestring. This difference can create confusion.

The question_text and choice_text attributes return Unicode values already.

Share:
14,297

Related videos on Youtube

bhavya
Author by

bhavya

noob programmer

Updated on June 04, 2022

Comments

  • bhavya
    bhavya 8 days

    I am Learning Django using the Django project tutorial. Since I use python 2.7 I am unable to implement the following in python 2.7:

    from django.db import models
    
    class Question(models.Model):
    # ...
        def __str__(self):              # __unicode__ on Python 2
            return self.question_text
    
    class Choice(models.Model):
    # ...
        def __str__(self):              # __unicode__ on Python 2
            return self.choice_text
    
    • neosergio
      neosergio about 6 years
      Accepted answer should be that one from @alfetopito, because that technique is the best match for Django’s porting philosophy.
  • RompePC
    RompePC over 5 years
    I just passed along this post, and I think will be nice to note that you can make a recursion depth exception if you try to use a child __str__ that calls its parent's __str__ with that decorator. Something to be aware of. Sorry for the necro.