Ver índice de contenidos del libro

5.9. Agregar strings de representación del modelo

Cuando imprimimos la lista de editores, todo lo que obtuvimos fue esta salida poco útil que hacía difícil distinguir los objetos Publisher:

[<Publisher: Publisher object>, <Publisher: Publisher object>]

Podemos arreglar esto fácilmente agregando un método llamado __str__() a nuestro objeto Publisher. Un método __str__() le dice a Python como mostrar la representación "string" de un objeto. Puedes ver esto en acción agregando un método __str__() a los tres modelos:

from django.db import models
 
class Publisher(models.Model):
    name = models.CharField(maxlength=30)
    address = models.CharField(maxlength=50)
    city = models.CharField(maxlength=60)
    state_province = models.CharField(maxlength=30)
    country = models.CharField(maxlength=50)
    website = models.URLField()
 
    def __str__(self):
        return self.name
 
class Author(models.Model):
    salutation = models.CharField(maxlength=10)
    first_name = models.CharField(maxlength=30)
    last_name = models.CharField(maxlength=40)
    email = models.EmailField()
    headshot = models.ImageField(upload_to='/tmp')
 
    def __str__(self):
        return '%s %s' % (self.first_name, self.last_name)
 
class Book(models.Model):
    title = models.CharField(maxlength=100)
    authors = models.ManyToManyField(Author)
    publisher = models.ForeignKey(Publisher)
    publication_date = models.DateField()
 
    def __str__(self):
        return self.title

Como puedes ver, un método __str__() puede hacer lo que sea que necesite hacer para devolver una representación textual. Aquí, los métodos __str__() de Publisher y Book devuelven simplemente el nombre y título del objeto respectivamente, pero el __str__() del Author es un poco más complejo — junta los campos first_name y last_name. El único requerimiento para __str__() es que devuelva un string. Si __str__() no devuelve un string — si retorna, digamos, un entero -- entonces Python generará un TypeError con un mensaje como "__str__ returned non-string".

Para que los cambios sean efectivos, sal del shell Python y entra de nuevo con python manage.py shell. (Esta es la manera más simple de hacer que los cambios en el código tengan efecto.) Ahora la lista de objetos Publisher es más fácil de entender:

>>> from books.models import Publisher
>>> publisher_list = Publisher.objects.all()
>>> publisher_list
[<Publisher: Addison-Wesley>, <Publisher: O'Reilly>]

Asegúrate de que cada modelo que definas tenga un método __str__() — no solo por tu propia conveniencia cuando usas el intérprete interactivo, sino también porque Django usa la salida de __str__() en muchos lugares cuando necesita mostrar objetos.

Finalmente, observa que __str__() es un buen ejemplo de agregar comportamiento a los modelos. Un modelo Django describe más que la configuración de la tabla de la base de datos; también describe toda funcionalidad que el objeto sepa hacer. __str__() es un ejemplo de esa funcionalidad — un modelo sabe cómo mostrarse.