Fixed #21951 -- Updated docs to use __str__ for Python 3
Thanks Tim Graham for the report and recommendations
This commit is contained in:
parent
c3434fed5b
commit
8aa1efff6d
|
@ -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.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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?>]
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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::
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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::
|
||||||
|
|
|
@ -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``.
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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):
|
||||||
|
|
Loading…
Reference in New Issue