Fixed #21951 -- Updated docs to use __str__ for Python 3

Thanks Tim Graham for the report and recommendations
This commit is contained in:
Alasdair Nicol 2014-02-09 11:38:13 +00:00 committed by Tim Graham
parent c3434fed5b
commit 8aa1efff6d
20 changed files with 71 additions and 72 deletions

View File

@ -817,13 +817,13 @@ smoothly:
a field that's similar to what you want and extend it a little bit, a field that's similar to what you want and extend it a little bit,
instead of creating an entirely new field from scratch. instead of creating an entirely new field from scratch.
2. Put a ``__str__()`` or ``__unicode__()`` method on the class you're 2. Put a ``__str__()`` (``__unicode__()`` on Python 2) method on the class you're
wrapping up as a field. There are a lot of places where the default wrapping up as a field. There are a lot of places where the default
behavior of the field code is to call behavior of the field code is to call
:func:`~django.utils.encoding.force_text` on the value. (In our :func:`~django.utils.encoding.force_text` on the value. (In our
examples in this document, ``value`` would be a ``Hand`` instance, not a examples in this document, ``value`` would be a ``Hand`` instance, not a
``HandField``). So if your ``__unicode__()`` method (``__str__()`` on ``HandField``). So if your ``__str__()`` method (``__unicode__()`` on
Python 3) automatically converts to the string form of your Python object, Python 2) automatically converts to the string form of your Python object,
you can save yourself a lot of work. you can save yourself a lot of work.

View File

@ -727,7 +727,7 @@ Save these changes and start a new Python interactive shell by running
>>> from polls.models import Question, Choice >>> from polls.models import Question, Choice
# Make sure our __unicode__() addition worked. # Make sure our __str__() addition worked.
>>> Question.objects.all() >>> Question.objects.all()
[<Question: What's up?>] [<Question: What's up?>]

View File

@ -57,8 +57,7 @@ simple news application with an ``Article`` model::
body = models.TextField() body = models.TextField()
status = models.CharField(max_length=1, choices=STATUS_CHOICES) status = models.CharField(max_length=1, choices=STATUS_CHOICES)
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self):
return self.title return self.title
A common task we might perform with a model like this is to update an A common task we might perform with a model like this is to update an

View File

@ -512,7 +512,7 @@ subclass::
list_display = ('first_name', 'last_name') list_display = ('first_name', 'last_name')
If you don't set ``list_display``, the admin site will display a single If you don't set ``list_display``, the admin site will display a single
column that displays the ``__unicode__()`` (``__str__()`` on Python 3) column that displays the ``__str__()`` (``__unicode__()`` on Python 2)
representation of each object. representation of each object.
You have four possible values that can be used in ``list_display``: You have four possible values that can be used in ``list_display``:
@ -563,7 +563,7 @@ subclass::
A few special cases to note about ``list_display``: A few special cases to note about ``list_display``:
* If the field is a ``ForeignKey``, Django will display the * If the field is a ``ForeignKey``, Django will display the
``__unicode__()`` (``__str__()`` on Python 3) of the related object. ``__str__()`` (``__unicode__()`` on Python 2) of the related object.
* ``ManyToManyField`` fields aren't supported, because that would * ``ManyToManyField`` fields aren't supported, because that would
entail executing a separate SQL statement for each row in the table. entail executing a separate SQL statement for each row in the table.
@ -626,11 +626,11 @@ subclass::
list_display = ('name', 'born_in_fifties') list_display = ('name', 'born_in_fifties')
* The ``__str__()`` and ``__unicode__()`` methods are just as valid in * The ``__str__()`` (``__unicode__()`` on Python 2) method is just
``list_display`` as any other model method, so it's perfectly OK to as valid in ``list_display`` as any other model method, so it's
do this:: perfectly OK to do this::
list_display = ('__unicode__', 'some_other_field') list_display = ('__str__', 'some_other_field')
* Usually, elements of ``list_display`` that aren't actual database * Usually, elements of ``list_display`` that aren't actual database
fields can't be used in sorting (because Django does all the sorting fields can't be used in sorting (because Django does all the sorting

View File

@ -259,8 +259,7 @@ A simple example is a tagging system, which might look like this::
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id') content_object = GenericForeignKey('content_type', 'object_id')
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self):
return self.tag return self.tag
A normal :class:`~django.db.models.ForeignKey` can only "point A normal :class:`~django.db.models.ForeignKey` can only "point

View File

@ -65,7 +65,7 @@ of using ``ogrinspect`` :ref:`in the tutorial <ogrinspect-intro>`.
.. django-admin-option:: --name-field <name_field> .. django-admin-option:: --name-field <name_field>
Generates a ``__unicode__`` routine (``__str__`` on Python 3) on the model Generates a ``__str__`` routine (``__unicode__`` on Python 2) on the model
that will return the given field name. that will return the given field name.
.. django-admin-option:: --no-imports .. django-admin-option:: --no-imports

View File

@ -61,8 +61,7 @@ Example
poly = models.PolygonField(srid=4269) # we want our model in a different SRID poly = models.PolygonField(srid=4269) # we want our model in a different SRID
objects = models.GeoManager() objects = models.GeoManager()
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self):
return 'Name: %s' % self.name return 'Name: %s' % self.name
3. Use :class:`LayerMapping` to extract all the features and place them in the 3. Use :class:`LayerMapping` to extract all the features and place them in the

View File

@ -244,8 +244,7 @@ model to represent this data::
objects = models.GeoManager() objects = models.GeoManager()
# Returns the string representation of the model. # Returns the string representation of the model.
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self):
return self.name return self.name
Please note two important things: Please note two important things:

View File

@ -653,16 +653,16 @@ Customizing the error list format
By default, forms use ``django.forms.utils.ErrorList`` to format validation By default, forms use ``django.forms.utils.ErrorList`` to format validation
errors. If you'd like to use an alternate class for displaying errors, you can errors. If you'd like to use an alternate class for displaying errors, you can
pass that in at construction time (replace ``__unicode__`` by ``__str__`` on pass that in at construction time (replace ``__str__`` by ``__unicode__`` on
Python 3):: Python 2)::
>>> from django.forms.utils import ErrorList >>> from django.forms.utils import ErrorList
>>> class DivErrorList(ErrorList): >>> class DivErrorList(ErrorList):
... def __unicode__(self): ... def __str__(self): # __unicode__ on Python 2
... return self.as_divs() ... return self.as_divs()
... def as_divs(self): ... def as_divs(self):
... if not self: return u'' ... if not self: return ''
... return u'<div class="errorlist">%s</div>' % ''.join([u'<div class="error">%s</div>' % e for e in self]) ... return '<div class="errorlist">%s</div>' % ''.join(['<div class="error">%s</div>' % e for e in self])
>>> f = ContactForm(data, auto_id=False, error_class=DivErrorList) >>> f = ContactForm(data, auto_id=False, error_class=DivErrorList)
>>> f.as_p() >>> f.as_p()
<div class="errorlist"><div class="error">This field is required.</div></div> <div class="errorlist"><div class="error">This field is required.</div></div>
@ -687,8 +687,8 @@ lazy developers -- they're not the only way a form object can be displayed.
Used to display HTML or access attributes for a single field of a Used to display HTML or access attributes for a single field of a
:class:`Form` instance. :class:`Form` instance.
The ``__unicode__()`` and ``__str__()`` methods of this object displays The ``__str__()`` (``__unicode__`` on Python 2) method of this
the HTML for this field. object displays the HTML for this field.
To retrieve a single ``BoundField``, use dictionary lookup syntax on your form To retrieve a single ``BoundField``, use dictionary lookup syntax on your form
using the field's name as the key:: using the field's name as the key::

View File

@ -1047,7 +1047,7 @@ objects (in the case of ``ModelMultipleChoiceField``) into the
initial value, no empty choice is created (regardless of the value initial value, no empty choice is created (regardless of the value
of ``empty_label``). of ``empty_label``).
The ``__unicode__`` (``__str__`` on Python 3) method of the model will be The ``__str__`` (``__unicode__`` on Python 2) method of the model will be
called to generate string representations of the objects for use in the called to generate string representations of the objects for use in the
field's choices; to provide customized representations, subclass field's choices; to provide customized representations, subclass
``ModelChoiceField`` and override ``label_from_instance``. This method will ``ModelChoiceField`` and override ``label_from_instance``. This method will

View File

@ -463,9 +463,29 @@ the conversion to string objects when required.
.. method:: Model.__str__() .. method:: Model.__str__()
The ``__str__()`` method is called whenever you call ``str()`` on an object. The main use for this method directly inside Django is when the ``repr()`` output of a model is displayed anywhere (for example, in debugging output). The ``__str__()`` method is called whenever you call ``str()`` on an
Thus, you should return a nice, human-readable string for the object's object. In Python 3, Django uses ``str(obj)`` in a number of
``__str__()``. It isn't required to put ``__str__()`` methods everywhere if you have sensible :meth:`~Model.__unicode__()` methods. places. Most notably, to display an object in the Django admin site
and as the value inserted into a template when it displays an
object. Thus, you should always return a nice, human-readable
representation of the model from the ``__str__()`` method.
For example::
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
def __str__(self):
return '%s %s' % (self.first_name, self.last_name)
In Python 2, the main use of ``__str__`` directly inside Django is
when the ``repr()`` output of a model is displayed anywhere (for
example, in debugging output). It isn't required to put ``__str__()``
methods everywhere if you have sensible :meth:`~Model.__unicode__()`
methods.
The previous :meth:`~Model.__unicode__()` example could be similarly written The previous :meth:`~Model.__unicode__()` example could be similarly written
using ``__str__()`` like this:: using ``__str__()`` like this::

View File

@ -812,17 +812,16 @@ For example, suppose you have these models::
name = models.CharField(max_length=50) name = models.CharField(max_length=50)
toppings = models.ManyToManyField(Topping) toppings = models.ManyToManyField(Topping)
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self): return "%s (%s)" % (self.name, ", ".join([topping.name
return u"%s (%s)" % (self.name, u", ".join([topping.name for topping in self.toppings.all()]))
for topping in self.toppings.all()]))
and run:: and run::
>>> Pizza.objects.all() >>> Pizza.objects.all()
[u"Hawaiian (ham, pineapple)", u"Seafood (prawns, smoked salmon)"... ["Hawaiian (ham, pineapple)", "Seafood (prawns, smoked salmon)"...
The problem with this is that every time ``Pizza.__unicode__()`` asks for The problem with this is that every time ``Pizza.__str__()`` asks for
``self.toppings.all()`` it has to query the database, so ``self.toppings.all()`` it has to query the database, so
``Pizza.objects.all()`` will run a query on the Toppings table for **every** ``Pizza.objects.all()`` will run a query on the Toppings table for **every**
item in the Pizza ``QuerySet``. item in the Pizza ``QuerySet``.

View File

@ -984,8 +984,7 @@ authentication app::
# The user is identified by their email address # The user is identified by their email address
return self.email return self.email
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self):
return self.email return self.email
def has_perm(self, perm, obj=None): def has_perm(self, perm, obj=None):

View File

@ -89,8 +89,7 @@ We'll be using these models::
class Meta: class Meta:
ordering = ["-name"] ordering = ["-name"]
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self):
return self.name return self.name
class Author(models.Model): class Author(models.Model):
@ -99,8 +98,7 @@ We'll be using these models::
email = models.EmailField() email = models.EmailField()
headshot = models.ImageField(upload_to='author_headshots') headshot = models.ImageField(upload_to='author_headshots')
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self):
return self.name return self.name
class Book(models.Model): class Book(models.Model):

View File

@ -16,8 +16,7 @@ objects, and a ``Publication`` has multiple ``Article`` objects:
class Publication(models.Model): class Publication(models.Model):
title = models.CharField(max_length=30) title = models.CharField(max_length=30)
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self):
return self.title return self.title
class Meta: class Meta:
@ -27,8 +26,7 @@ objects, and a ``Publication`` has multiple ``Article`` objects:
headline = models.CharField(max_length=100) headline = models.CharField(max_length=100)
publications = models.ManyToManyField(Publication) publications = models.ManyToManyField(Publication)
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self):
return self.headline return self.headline
class Meta: class Meta:

View File

@ -15,17 +15,15 @@ To define a many-to-one relationship, use :class:`~django.db.models.ForeignKey`.
last_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30)
email = models.EmailField() email = models.EmailField()
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self): return "%s %s" % (self.first_name, self.last_name)
return u"%s %s" % (self.first_name, self.last_name)
class Article(models.Model): class Article(models.Model):
headline = models.CharField(max_length=100) headline = models.CharField(max_length=100)
pub_date = models.DateField() pub_date = models.DateField()
reporter = models.ForeignKey(Reporter) reporter = models.ForeignKey(Reporter)
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self):
return self.headline return self.headline
class Meta: class Meta:

View File

@ -16,26 +16,23 @@ In this example, a ``Place`` optionally can be a ``Restaurant``:
name = models.CharField(max_length=50) name = models.CharField(max_length=50)
address = models.CharField(max_length=80) address = models.CharField(max_length=80)
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self): return "%s the place" % self.name
return u"%s the place" % self.name
class Restaurant(models.Model): class Restaurant(models.Model):
place = models.OneToOneField(Place, primary_key=True) place = models.OneToOneField(Place, primary_key=True)
serves_hot_dogs = models.BooleanField() serves_hot_dogs = models.BooleanField()
serves_pizza = models.BooleanField() serves_pizza = models.BooleanField()
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self): return "%s the restaurant" % self.place.name
return u"%s the restaurant" % self.place.name
class Waiter(models.Model): class Waiter(models.Model):
restaurant = models.ForeignKey(Restaurant) restaurant = models.ForeignKey(Restaurant)
name = models.CharField(max_length=50) name = models.CharField(max_length=50)
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self): return "%s the waiter at %s" % (self.name, self.restaurant)
return u"%s the waiter at %s" % (self.name, self.restaurant)
What follows are examples of operations that can be performed using the Python What follows are examples of operations that can be performed using the Python
API facilities. API facilities.

View File

@ -417,16 +417,14 @@ something like this::
class Person(models.Model): class Person(models.Model):
name = models.CharField(max_length=128) name = models.CharField(max_length=128)
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self):
return self.name return self.name
class Group(models.Model): class Group(models.Model):
name = models.CharField(max_length=128) name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership') members = models.ManyToManyField(Person, through='Membership')
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self):
return self.name return self.name
class Membership(models.Model): class Membership(models.Model):

View File

@ -23,16 +23,14 @@ models, which comprise a Weblog application:
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
tagline = models.TextField() tagline = models.TextField()
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self):
return self.name return self.name
class Author(models.Model): class Author(models.Model):
name = models.CharField(max_length=50) name = models.CharField(max_length=50)
email = models.EmailField() email = models.EmailField()
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self):
return self.name return self.name
class Entry(models.Model): class Entry(models.Model):
@ -46,8 +44,7 @@ models, which comprise a Weblog application:
n_pingbacks = models.IntegerField() n_pingbacks = models.IntegerField()
rating = models.IntegerField() rating = models.IntegerField()
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self):
return self.headline return self.headline
Creating objects Creating objects

View File

@ -162,8 +162,7 @@ Consider this set of models::
title = models.CharField(max_length=3, choices=TITLE_CHOICES) title = models.CharField(max_length=3, choices=TITLE_CHOICES)
birth_date = models.DateField(blank=True, null=True) birth_date = models.DateField(blank=True, null=True)
# On Python 3: def __str__(self): def __str__(self): # __unicode__ on Python 2
def __unicode__(self):
return self.name return self.name
class Book(models.Model): class Book(models.Model):