Django Book: отображение строк моделей

Автор: | 03/05/2015
 

django_logo_2Предыдущая часть.

Когда мы выводим на экран список издателей — всё, что мы получаем — это бесполезное отображение, которое делает сложным работу с отдельными объектами Publisher:

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

Мы можем легко это исправить, добавив вызов метода __unicode__() в наш класс Publisher. Метод __unicode__() указывает Python-у как отображать Unicode-предсталвение объекта.  Вы можете увидеть его работу, добавив этот метод к вашим моделям:

from django.db import models

class Publisher(models.Model):
    name = models.CharField(max_length=30)
    address = models.CharField(max_length=50)
    city = models.CharField(max_length=60)
    state_province = models.CharField(max_length=30)
    country = models.CharField(max_length=50)
    website = models.URLField()

    def __unicode__(self):
        return self.name

class Author(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=40)
    email = models.EmailField()

    def __unicode__(self):
        return u'%s %s' % (self.first_name, self.last_name)

class Book(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author)
    publisher = models.ForeignKey(Publisher)
    publication_date = models.DateField()

    def __unicode__(self):
        return self.title

Как вы видите, метод __unicode__() делает всё необходимое для того, что бы вернуть представление объекта. Тут для Publisher и Book он просто возвращает имя и заголовок объекта, а для Author метод немного более сложный — он передаёт значения first_name  и last_name  вместе, разделённые пробелом.

Главное требование к методу  __unicode__() — что бы возвращал объект Unicode. Если он вернёт, например, тип integerPython вызовет ошибку TypeError  с сообщением типа «coercing to Unicode: need string or buffer, int found«.

Объекты Unicode

Что такое объекты Unicode?

Вы можете представлять себе объекты Unicode как строки Python, которые могут содержать более миллиона типов символов, от подчёркнутых латинских символов  до не-латинских фигурных кавычек и других знаков.

Обычные строки Python используют кодировку ASCIIISO-8859-1 или UTF-8 Если вы храните в строке какие-то причудливые символы (что угодно, не входящее в стандартную 128-символьную таблицу ASCII, т.е. такие символы как цифры от 0 до 9 и буквы от A до Z) — вам следует позаботиться о том, в какой кодировке эту строку использовать, иначе ваши символы могут отображать неверно. Проблема может возникнуть, когда вы храните данные в одной кодировке, и пытаетесь комбинировать её с данными в другой, или пытаетесь отобразить строку в приложении, которое предполагает определённую кодировку. Мы все встречали веб-страницы или письма с смиволами «????? ???» или другими символами в тексте. Это обычно и означает проблему с кодировкой.

Однако, объекты Unicode не используют кодировку вообще — они используют универсальный набор символов, который и называется Unicode. Когда вы имеете дело с объектами Unicode в Python — вы можете использовать их без проблем и не переживать о проблемах с кодировкой.

Djnago использует Unicode повсюду. Объекты моделей получаются в виде объектов Unicode, представления взаимодействуют с данными Unicode, шаблоны рендерятся как Unicode. Как правило — вам не стоит переживать о том, что бы использовать правльную кодировку символов — всё должно работать без вмешательства.

Имеется полезный обзор объектов Unicode, и вам может быть интересно познакомиться с ним поближе. Хороший ресурс, что бы этим заняться — статья http://www.joelonsoftware.com/articles/Unicode.html .

Что бы наши изменения с методом __unicode__() заработали — выйдите и снова запустите python manage.py shell. Теперь список объектов Publisher выглядит намного понятнее:

In [1]: from books.models import Publisher

In [2]: publisher_list = Publisher.objects.all()

In [3]: print(publisher_list)
[<Publisher: Apress>, <Publisher: O'Reilly>]

Убедитесь, что каждая модель имеет метод __unicode__() — не только для вашего собственного удобства при роботе в консоли, но так же потому что Djnago использует Unicode в некоторых местах, где требуется отобразить объекты.

Напоследок — обратите внимание, что показанный пример с методом __unicode__()  хорошо демонстрирует то, как можно изменить поведение объектов. Модель Django описывает больше, чем просто представление ваших данных в базе данных — она так же описывает любой функционал, который объект должен выполнять. __unicode__() — один из таких примеров функционала — теперь модель «знает» как она себя должна отображать.

Продолжение — Django Book: добавление и обновление данных.