Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Django_-_podrobnoe_rukovodstvo

.pdf
Скачиваний:
373
Добавлен:
01.03.2016
Размер:
5 Мб
Скачать
☆

410

Приложение A. Справочник по моделям

Класс TextField

Длинное текстовое поле.

Для хранения не слишком больших текстов лучше использовать класс

CharField.

Класс TimeField

Время, представленное объектом класса Python datetime.time. Принимает те же параметры, заполняемые автоматически, что и DateField.

Класс URLField

Подкласс класса CharField для хранения URL; конструктор имеет один дополнительный необязательный аргумент:

verify_exists

Если аргумент имеет значение True (по умолчанию), то проверяется существование URL (то есть тот факт, что страницу по этому адресу можно загрузить, не получив ошибку 404). Отметим, что при работе с однопоточным сервером разработки проверка URL, выполняемая на том же сервере, занимает его на достаточно длительное время, и складывается впечатление, будто сервер «завис». Для многопоточных серверов такой проблемы не возникает.

Как и все подклассы CharField, класс URLField принимает необязательный аргумент max_length. Если он не определен, по умолчанию используется значение 200.

Класс XMLField

Подкласс класса TextField, который проверяет, является ли содержимое поля допустимым XML-документом, отвечающим указанной схеме. Конструктор принимает один обязательный аргумент:

schema_path

Это путь к файлу, содержащему схему на языке RelaxNG, по которой проверяется значение поля. Подробнее о языке RelaxNG см. http://www. relaxng.org/.

Универсальные параметры поля

Следующие аргументы можно определять для полей любого типа. Все они необязательны.

Параметр null

Если имеет значение True, пустые значения будут сохраняться в базе данных как значение NULL; в противном случае попытка сохранить пу-

Универсальные параметры поля

411

стое значение, скорее всего, приведет к ошибке базы данных. По умолчанию равен False.

Отметим, что пустые строковые значения всегда сохраняются как пустые строки, а не как значение NULL. Значение null=True следует использовать только для не-строковых полей, например, целых чисел, булевских значений и дат. В любом случае нужно также задать blank=True, чтобы разрешить оставлять незаполненные поля в формах, так как параметр null влияет только на сохранение в базе данных (см. раздел «Параметр blank»).

Не используйте параметр null для строковых полей, например CharField и TextField, если на то нет веской причины. Если для строкового поля задано null=True, то образуется два способа выразить семантику «отсутствия данных»: NULL и пустая строка. В большинстве случаев такая неоднозначность ни к чему; в Django принято соглашение использовать в этом случае пустую строку, а не NULL.

Примечание

При работе с СУБД Oracle параметр null=True принудительно задается для строковых полей, допускающих пустые значения, и для обозначения пустой строки в базу данных записывается NULL.

Дополнительную информацию по этому поводу см. в разделе «Как сделать необязательными поля даты и числовые поля» главы 6.

Параметр blank

Если имеет значение True, то поле может быть оставлено пустым. По умолчанию False.

Отметим, что этот параметр отличается от null. Последний относится только к базе данных, тогда как первый – к проверке данных. Если для некоторого поля определен атрибут blank=True, то административный интерфейс Django позволит не заполнять его. Если же указан атрибут blank=False, то поле должно быть заполнено обязательно.

Параметр choices

Итерируемый объект (например, список или кортеж), каждым элементом которого является описание одного из допустимых значений поля.

Список choices выглядит следующим образом:

YEAR_IN_SCHOOL_CHOICES = ( (‘FR’, ‘Freshman’), (‘SO’, ‘Sophomore’), (‘JR’, ‘Junior’), (‘SR’, ‘Senior’), (‘GR’, ‘Graduate’),

)

412

Приложение A. Справочник по моделям

Первый элемент в каждом кортеже – фактическое сохраняемое значение, второй – понятное для человека описание.

Список choices можно включить в класс модели:

class Foo(models.Model): GENDER_CHOICES = (

(‘М’, ‘Мужчина’), (‘Ж’, ‘Женщина’),

)

gender = models.CharField(max_length=1, choices=GENDER_CHOICES)

А можно определить и вне класса модели:

GENDER_CHOICES = ( (‘М’, ‘Мужчина’), (‘Ж’, ‘Женщина’),

)

class Foo(models.Model):

gender = models.CharField(max_length=1, choices=GENDER_CHOICES)

Можно также объединить допустимые варианты в именованные группы для более осмысленного расположения в форме:

MEDIA_CHOICES = ( (‘Audio’, (

(‘vinyl’, ‘Vinyl’), (‘cd’, ‘CD’),

)

), (‘Video’, (

(‘vhs’, ‘VHS Tape’), (‘dvd’, ‘DVD’),

)

),

(‘unknown’, ‘Unknown’),

)

Первый элемент в каждом кортеже – имя группы, второй – итерируемый объект, кортеж из двух элементов, каждый из которых содержит значение и понятное человеку описание варианта. Сгруппированные варианты можно объединять в один список с несгруппированными (как в случае варианта unknown выше).

Наконец, отметим, что варианты могут быть представлены любым итерируемым объектом, не обязательно списком или кортежем. Это позволяет конструировать варианты динамически. Но для динамического построения параметра choices лучше воспользоваться таблицей базы данных с внешним ключом (полем типа ForeignKey). Параметр choices все же предназначен для описания статических данных, которые изменяются редко.

Универсальные параметры поля

413

Параметр db_column

Имя столбца базы данных, соответствующего данному полю. Если этот параметр не определен, Django будет использовать имя поля.

Ничего страшного не произойдет, если имя столбца базы данных – зарезервированное слово языка SQL или содержит символы, недопустимые в именах переменных Python (прежде всего, дефис). Django заключает имена таблиц и столбцов в кавычки.

Параметр db_index

Если имеет значение True, то команда django-admin.py sqlindexes сгенерирует для данного поля предложение CREATE INDEX.

Параметр db_tablespace

Имя табличного пространства, куда следует поместить индекс по данному полю, если оно индексируется. По умолчанию берется из параметра

DEFAULT_INDEX_TABLESPACE, если он задан, или из параметра db_tablespace

для модели, если таковой присутствует. Если СУБД не поддерживает табличные пространства, то этот параметр игнорируется.

Параметр default

Значение поля по умолчанию; может быть значением или вызываемым объектом. В последнем случае объект будет вызываться при создании каждого экземпляра модели.

Параметр editable

Если имеет значение False, то поле будет запрещено изменять в административном интерфейсе или в формах, автоматически сгенерированных по классу модели. По умолчанию True.

Параметр help_text

Дополнительное пояснение, отображаемое под данным полем в форме административного интерфейса. Даже если объект не представлен в административном интерфейсе, этот параметр полезно использовать для документирования.

Отметим, что при отображении в административном интерфейсе HTML-разметка, содержащаяся в значении этого параметра, не экранируется. Поэтому вы можете включать в пояснительный текст HTMLтеги. Например:

help_text=”Дату следует вводить в формате <em>ГГГГ-ММ-ДД</em>.”

Но можно выполнить экранирование самостоятельно с помощью функции django.utils.html.escape().

414

Приложение A. Справочник по моделям

Параметр primary_key

Если имеет значение True, то данное поле является первичным ключом.

Если ни для одного поля модели не определен параметр primary_key=True, то Django автоматически добавит поле типа AutoField, которое станет первичным ключом, поэтому наличие primary_key=True необязательно, если только вы не хотите задать первичный ключ явно.

При наличии primary_key=True автоматически устанавливаются параметры null=False и unique=True. Для объекта может быть определен только один первичный ключ.

Параметр unique

Если имеет значение True, то все значения в этом поле должны быть уникальны.

Это гарантируется на уровне СУБД и проверяется в формах, создаваемых с помощью ModelForm (в том числе и в административном интерфейсе). Если при сохранении объекта модели обнаружится дубликат, то метод save возбудит исключение IntegrityError.

Этот параметр можно задавать для полей всех типов, кроме

ManyToManyField, FileField и ImageField.

Параметр unique_for_date

Задайте в этом параметре имя поля типа DateField или DateTimeField, если хотите, чтобы в таблице не было двух одинаковых значений данного поля с одинаковыми датами в указанном поле.

Например, если в модели есть поле title, для которого unique_for_ date=”pub_date”, то Django не позволит ввести две записи с одинаковыми значениями в полях title и pub_date.

Это ограничение проверяется на уровне форм, созданных с помощью ModelForm (в том числе и в административном интерфейсе), но не на уровне базы данных.

Параметр unique_for_month

Аналогичен unique_for_date, но уникальным должен быть только месяц.

Параметр unique_for_year

Аналогичен unique_for_date и unique_for_month.

Параметр verbose_name

Понятное человеку описание поля. Если этот параметр не определен, то Django автоматически возьмет значение атрибута name, заменив в нем символы подчеркивания пробелами.

Отношения

415

Отношения

Совершенно очевидно, что мощь реляционных баз данных обусловлена возможностью определять отношения между таблицами. Django позволяет определить три наиболее употребительных типа отношений: многие-к-одному, многие-ко-многим и один-к-одному.

Класс ForeignKey

Отношение многие-к-одному. Конструктор принимает обязательный позиционный параметр – класс модели, с которой связана отношением данная модель.

Чтобы создать рекурсивное отношение, когда модель связана отношением многие-к-одному сама с собой, используйте определение models. ForeignKey(‘self’).

Если потребуется создать связь с моделью, которая еще не определена, можно указать не сам класс модели, а его имя в виде строки:

class Car(models.Model):

manufacturer = models.ForeignKey(‘Manufacturer’)

# ...

class Manufacturer(models.Model):

# ...

Отметим, однако, что это относится лишь к моделям, определенным

водном и том же файле models.py. Чтобы сослаться на модели, определенные в другом приложении, необходимо явно указать метку приложения. Например, если допустить, что модель Manufacturer определена

вприложении production, то отношение должно быть определено так:

class Car(models.Model):

manufacturer = models.ForeignKey(‘production.Manufacturer’)

Чтобы получить имя столбца в базе данных, Django незаметно для вас добавит суффикс “_id” к имени поля. В примере выше в таблице базы данных для модели Car появится столбец manufacturer_id (имя можно изменить, указав его явно с помощью параметра db_column). Однако вам редко придется иметь дело с именами столбцов, разве что если вы пишете SQL-команды самостоятельно. Как правило, вы будете иметь дело только с именами полей модели.

Конструктор класса ForeignKey принимает также дополнительные параметры (все они необязательны), с помощью которых можно уточнить поведение отношения.

Параметр limit_choices_to

Словарь, ограничивающий набор вариантов, доступных в административном интерфейсе для данного объекта. Можно использовать с функциями из модуля datetime для наложения ограничений по дате. Вот, на-

416

Приложение A. Справочник по моделям

пример, как ограничить выбор связанных объектов только теми, для которых значение поля pub_date раньше текущего момента:

limit_choices_to = {‘pub_date__lte’: datetime.now}

limit_choices_to не влияет на встроенные объекты FormSet, которые создаются для отображения связанных объектов в административным интерфейсе.

Параметр related_name

Имя, по которому связанная модель будет ссылаться на данную.

Параметр to_field

Поле в связанной модели, указанной в данном отношении. По умолчанию Django использует имя первичного ключа, определенного в связанной модели.

Класс ManyToManyField

Отношение многие-ко-многим. Конструктор принимает обязательный позиционный параметр – класс модели, с которой связана отношением данная модель. Работает точно так же, как в классе ForeignKey, включая возможность определения рекурсивных и опережающих связей.

Для представления отношения многие-ко-многим Django за кулисами создает промежуточную связующую таблицу. По умолчанию имя этой таблицы образуется из имен двух соединяемых таблиц. Поскольку некоторые СУБД не поддерживают длинные имена таблиц, то получившееся имя автоматически обрезается до 64 знаков, а для гарантии уникальности добавляется автоматически генерируемый суффикс. Поэтому не удивляйтесь, увидев имя вида author_books_9cdf4, – это абсолютно нормально. Параметр db_table позволяет определить имя связующей таблицы вручную.

Конструктор класса ManyToManyField принимает также дополнительные параметры (все они необязательны), с помощью которых можно уточнить поведение отношения.

Параметр related_name

То же, что related_name в классе ForeignKey.

Параметр limit_choices_to

То же, что limit_choices_to в классе ForeignKey.

Параметр limit_choices_to игнорируется, если поле типа ManyToManyField используется совместно с нестандартной связующей таблицей, заданной параметром through.

Отношения

417

Параметр symmetrical

Используется только при определении отношения ManyToManyField с параметром self. Рассмотрим следующую модель:

class Person(models.Model):

friends = models.ManyToManyField(“self”)

При обработке этой модели Django обнаруживает отношение ManyToManyField модели с самой собой, поэтому не добавляет в класс Person атрибут person_set. Вместо этого предполагается, что связь ManyToManyField симметрична (если я – твой друг, то ты – мой друг).

Если вы не хотите, чтобы связь многие-ко-многим была симметричной, то передайте параметр symmetrical со значением False. Тогда Django добавит дескриптор для обратной связи, разрешая асимметрию

ManyToManyField.

Параметр through

Django автоматически создает связующую таблицу для реализации отношения многие-ко-многим. Но при желании вы можете определить ее самостоятельно, указав в параметре through модель, соответствующую этой таблице.

Обычно эта возможность применяется, когда с отношением многие-ко- многим необходимо ассоциировать дополнительные данные.

Параметр db_table

Имя связующей таблицы для отношения многие-ко-многим. Если не определено, по умолчанию будет образовано имя, состоящее из имен двух соединяемых таблиц.

Класс OneToOneField

Отношение один-к-одному. Концептуально аналогично ForeignKey с атрибутом unique=True, но в отличие от него каждый объект модели на «противоположной стороне» отношения связан с единственным объектом данной модели.

Обычно употребляется для определения первичного ключа модели, которая в некотором смысле «расширяет» данную; например, наследование таблиц реализуется путем явного добавления связи один-к-одному от дочерней модели к родительской.

Конструктор принимает один обязательный позиционный параметр – класс модели, с которой связывается данная модель. Работает точно так же, как в классе ForeignKey, включая возможность определения рекурсивных и опережающих связей.

Кроме того, конструктор класса OneToOneField принимает все дополнительные параметры, разрешенные для ForeignKey, плюс еще один:

418

Приложение A. Справочник по моделям

Параметр parent_link

Если имеет значение True и употребляется в модели, которая наследует другую (уточняемую) модель, то это означает, что для обратной ссылки на родительский класс следует использовать данное поле – вместо дополнительного поля типа OneToOneField, которое обычно неявно создается для реализации отношения класс-подкласс.

Метаданные модели

Метаданные модели располагаются в классе Meta, определенном внутри класса модели:

class Book(models.Model):

title = models.CharField(maxlength=100)

class Meta:

# Здесь находятся метаданные модели

...

К метаданным модели относится «все, что не является полем», например, параметры сортировки и прочее. В следующих разделах описаны все параметры метаданных, ни один из которых не является обязательным. Класс Meta можно вообще не включать, если он не нужен.

Параметр abstract

Если имеет значение True, то данная модель является абстрактным базовым классом. О том, что это такое, см. документацию по Django.

Параметр db_table

Имя таблицы базы данных, соответствующей данной модели:

db_table = ‘music_album’

Имена таблиц

В целях экономии времени Django автоматически формирует имя таблицы базы данных из имени класса модели и приложения, в котором этот класс находится. Имя таблицы образуется путем конкатенации метки приложения (имени, которое было указано в команде manage.py startapp), знака подчеркивания и имени класса модели.

Например, если в приложении bookstore (созданном командой manage.py startapp bookstore) определена модель Book, то в базе данных появится таблица bookstore_book.

Чтобы определить другое имя таблицы, воспользуйтесь параметром db_table в классе Meta.

Ничего страшного не произойдет, если имя таблицы – зарезервированное слово языка SQL или содержит символы, не допустимые в именах

Метаданные модели

419

переменных Python (прежде всего, дефис). Django заключает имена таблиц и столбцов в кавычки.

Параметр db_tablespace

Имя табличного пространства базы данных, в котором должна находиться соответствующая модели таблица. Если СУБД не поддерживает табличные пространства, этот параметр игнорируется.

Параметр get_latest_by

Имя поля модели типа DateField или DateTimeField. Определяет, какое поле будет по умолчанию использоваться в методе latest класса Manager.

Например:

get_latest_by = “order_date”

Параметр managed

По умолчанию имеет значение True, то есть Django будет создавать необходимые таблицы при выполнении команды django-admin.py syncdb и удалять их при выполнении команды reset. Иными словами, Django берет на себя управление таблицами базы данных.

Если параметру указать значение False, то для данной модели никакие объекты базы данных не создаются и не удаляются. Эту особенность можно использовать, когда модель описывает уже существующую таблицу или представление, созданные иными средствами. Это единственное, что отличает значения True и False данного параметра. Все остальные аспекты поведения модели одинаковы, в частности:

•• Если первичный ключ для модели не указан явно, он добавляется автоматически. Чтобы не вводить в заблуждение тех, кто будет читать ваш код, лучше описывать в неуправляемой модели все без исключения столбцы базы данных.

•• Если модель, для которой managed=False, содержит поле типа ManyTo­­ ManyField, указывающее на другую неуправляемую модель, то связующая таблица для соединения многие-ко-многим не создается. Однако для связи между управляемой и неуправляемой моделью связующая таблица создается.

Если вы хотите изменить это поведение, то явно создайте модель для связующей таблицы (задав параметр managed, как того требуют обстоятельства) и укажите ее с помощью атрибута through.

Для тестирования моделей, в которых определен атрибут managed=False, вы сами должны создать необходимые таблицы на этапе подготовки тестовой среды.