Ссылка на экземпляр модели
В данном документе описываются подробности API Model. Он основан на материалах, представленных в руководствах по моделям и запросам к базе данных, поэтому вам, вероятно, стоит прочитать и понять эти документы перед чтением этого.
В этом справочнике мы будем использовать пример моделей Weblog, представленных в руководстве по запросам к базе данных.
Создание объектов
Чтобы создать новый экземпляр модели, просто создайте его, как любой другой класс Python:
-
class Model(**kwargs)[source]
Ключевые аргументы — это просто имена полей, которые вы определили в своей модели. Обратите внимание, что создание экземпляра модели никак не затрагивает вашу базу данных; для этого вам нужно save().
Примечание
Вы можете быть искушены настроить модель, переопределяя метод __init__. Однако, если вы это сделаете, будьте внимательны, чтобы не изменять сигнатуру вызова, так как любые изменения могут помешать сохранению экземпляра модели. Вместо переопределения __init__, попробуйте использовать один из этих подходов:
-
Добавьте метод класса в класс модели:
from django.db import models class Book(models.Model): title = models.CharField(max_length=100) @classmethod def create(cls, title): book = cls(title=title) # do something with the book return book book = Book.create("Pride and Prejudice") -
Добавьте метод в пользовательский менеджер (обычно предпочтительнее):
class BookManager(models.Manager): def create_book(self, title): book = self.create(title=title) # do something with the book return book class Book(models.Model): title = models.CharField(max_length=100) objects = BookManager() book = Book.objects.create_book("Pride and Prejudice")
Настройка загрузки моделей
-
classmethod Model.from_db(db, field_names, values)[source]
Метод from_db() может использоваться для настройки создания экземпляра модели при загрузке из базы данных.
Аргумент db содержит псевдоним базы данных, из которой загружается модель, field_names содержит имена всех загруженных полей, а values содержит загруженные значения для каждого поля в field_names. field_names расположены в том же порядке, что и values. Если все поля модели присутствуют, то values гарантированно находятся в порядке, который __init__() ожидает. То есть, экземпляр можно создать с помощью cls(*values). Если какие-либо поля отложены, они не появятся в field_names. В этом случае присвойте значение django.db.models.DEFERRED каждому из отсутствующих полей.
Помимо создания новой модели, метод from_db() должен установить флаги adding и db в атрибуте _state нового экземпляра.
Ниже приведен пример, демонстрирующий, как записывать начальные значения полей, загружаемых из базы данных:
from django.db.models import DEFERRED
@classmethod
def from_db(cls, db, field_names, values):
# Default implementation of from_db() (subject to change and could
# be replaced with super()).
if len(values) != len(cls._meta.concrete_fields):
values = list(values)
values.reverse()
values = [
values.pop() if f.attname in field_names else DEFERRED
for f in cls._meta.concrete_fields
]
instance = cls(*values)
instance._state.adding = False
instance._state.db = db
# customization to store the original field values on the instance
instance._loaded_values = dict(zip(field_names, values))
return instance
def save(self, *args, **kwargs):
# Check how the current values differ from ._loaded_values. For example,
# prevent changing the creator_id of the model. (This example doesn't
# support cases where 'creator_id' is deferred).
if not self._state.adding and (
self.creator_id != self._loaded_values['creator_id']):
raise ValueError("Updating the value of creator isn't allowed")
super(...).save(*args, **kwargs)
Приведенный выше пример демонстрирует полную from_db() реализацию, чтобы прояснить, как это делается. В этом случае, конечно, было бы возможно просто использовать super() вызов в методе from_db().
В более ранних версиях вы могли проверить, были ли загружены все поля, обратившись к cls._deferred. Этот атрибут удален, и django.db.models.DEFERRED является новым.
Обновление объектов из базы данных
Если вы удаляете поле из экземпляра модели, при повторном доступе к нему происходит перезагрузка значения из базы данных:
>>> obj = MyModel.objects.first() >>> del obj.field >>> obj.field # Loads the field from the database
В более ранних версиях доступ к удалённому полю вызывал AttributeError вместо перезагрузки.
-
Model.refresh_from_db(using=None, fields=None)[source]
Если вам нужно перезагрузить значения модели из базы данных, вы можете использовать метод refresh_from_db(). При вызове этого метода без аргументов выполняется следующее:
- Все неотложенные поля модели обновляются до значений, которые в настоящее время присутствуют в базе данных.
- Предыдущие загруженные связанные экземпляры, для которых значение отношения больше недействительно, удаляются из перезагруженного экземпляра. Например, если у вас есть внешний ключ от перезагруженного экземпляра к другой модели с именем
Author, то еслиobj.author_id != obj.author.id,obj.authorбудут удалены, а при следующем обращении к ним они будут перезагружены со значениемobj.author_id.
Перезагружаются только поля модели из базы данных. Другие зависящие от базы данных значения, такие как аннотации, не перезагружаются. Также не очищаются атрибуты @cached_property.
Перезагрузка происходит из базы данных, из которой был загружен экземпляр, или из базы данных по умолчанию, если экземпляр не загружался из базы данных. Аргумент using может использоваться для принудительного использования базы данных для перезагрузки.
Можно принудительно задать набор загружаемых полей с помощью аргумента fields.
Например, чтобы проверить, что вызов update() привел к ожидаемому обновлению, вы могли бы написать тест, подобный этому:
def test_update_result(self):
obj = MyModel.objects.create(val=1)
MyModel.objects.filter(pk=obj.pk).update(val=F('val') + 1)
# At this point obj.val is still 1, but the value in the database
# was updated to 2. The object's updated value needs to be reloaded
# from the database.
obj.refresh_from_db()
self.assertEqual(obj.val, 2)
Обратите внимание, что при доступе к отложенным полям загрузка значения отложенного поля происходит через этот метод. Таким образом, можно настроить способ загрузки отложенных данных. Ниже приведен пример того, как можно перезагрузить все поля экземпляра при перезагрузке отложенного поля:
class ExampleModel(models.Model):
def refresh_from_db(self, using=None, fields=None, **kwargs):
# fields contains the name of the deferred field to be
# loaded.
if fields is not None:
fields = set(fields)
deferred_fields = self.get_deferred_fields()
# If any deferred field is going to be loaded
if fields.intersection(deferred_fields):
# then load all of them
fields = fields.union(deferred_fields)
super(ExampleModel, self).refresh_from_db(using, fields, **kwargs)
-
Model.get_deferred_fields()[source]
Вспомогательный метод, возвращающий набор имён атрибутов всех полей, которые в настоящее время отложены для этой модели.
Валидация объектов
Валидация модели включает три этапа:
- Валидация полей модели -
Model.clean_fields() - Валидация модели в целом -
Model.clean() - Валидация уникальности полей -
Model.validate_unique()
Все три этапа выполняются при вызове метода full_clean() модели.
При использовании ModelForm, вызов is_valid() выполнит эти этапы валидации для всех полей, включённых в форму. Смотрите документацию по формам ModelForm для получения дополнительной информации. Вам нужно вызывать метод full_clean() модели только если вы планируете самостоятельно обрабатывать ошибки валидации или если вы исключили поля из ModelForm, которые требуют валидации.
-
Model.full_clean(exclude=None, validate_unique=True)[source]
Этот метод вызывает Model.clean_fields(), Model.clean() и Model.validate_unique() (если validate_unique равно True), в указанном порядке и вызывает исключение ValidationError, у которого атрибут message_dict содержит ошибки со всех трёх этапов.
Необязательный аргумент exclude может использоваться для предоставления списка имён полей, которые можно исключить из валидации и очистки. ModelForm использует этот аргумент, чтобы исключить поля, отсутствующие в вашей форме, из валидации, поскольку любые возникающие ошибки не могут быть исправлены пользователем.
Обратите внимание, что full_clean() не будет вызываться автоматически при вызове метода save() модели. Вам нужно будет вызывать его вручную, когда вы захотите выполнить одношаговую валидацию модели для ваших собственных моделей, созданных вручную. Например:
from django.core.exceptions import ValidationError
try:
article.full_clean()
except ValidationError as e:
# Do something based on the errors contained in e.message_dict.
# Display them to a user, or handle them programmatically.
pass
Первый этап full_clean() — очистка каждого отдельного поля.
-
Model.clean_fields(exclude=None)[source]
Этот метод проверит все поля вашей модели. Необязательный аргумент exclude позволяет предоставить список имён полей, которые следует исключить из валидации. Он вызовет исключение ValidationError, если какая-либо валидация полей завершится неудачно.
Второй этап full_clean() — вызов Model.clean(). Этот метод следует переопределить для выполнения пользовательской валидации вашей модели.
-
Model.clean()[source]
Этот метод следует использовать для предоставления кастомной валидации модели и изменения атрибутов модели при необходимости. Например, вы можете использовать его для автоматического предоставления значения для поля или для валидации, требующей доступа к нескольким полям:
import datetime
from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import ugettext_lazy as _
class Article(models.Model):
...
def clean(self):
# Don't allow draft entries to have a pub_date.
if self.status == 'draft' and self.pub_date is not None:
raise ValidationError(_('Draft entries may not have a publication date.'))
# Set the pub_date for published items if it hasn't been set already.
if self.status == 'published' and self.pub_date is None:
self.pub_date = datetime.date.today()
Обратите внимание, что, как и Model.full_clean(), метод clean() модели не вызывается при вызове метода save() вашей модели.
В приведённом выше примере исключение ValidationError, поднятое методом Model.clean(), было создано со строкой, поэтому оно будет сохранено в специальном ключе словаря ошибок, NON_FIELD_ERRORS. Этот ключ используется для ошибок, связанных со всей моделью, а не с конкретным полем:
from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
try:
article.full_clean()
except ValidationError as e:
non_field_errors = e.message_dict[NON_FIELD_ERRORS]
Чтобы назначить исключения конкретному полю, создайте исключение ValidationError со словарем, где ключами являются имена полей. Мы можем обновить предыдущий пример, чтобы назначить ошибку полю pub_date:
class Article(models.Model):
...
def clean(self):
# Don't allow draft entries to have a pub_date.
if self.status == 'draft' and self.pub_date is not None:
raise ValidationError({'pub_date': _('Draft entries may not have a publication date.')})
...
Если вы обнаруживаете ошибки в нескольких полях во время Model.clean(), вы также можете передать словарь, сопоставляющий имена полей с ошибками:
raise ValidationError({
'title': ValidationError(_('Missing title.'), code='required'),
'pub_date': ValidationError(_('Invalid date.'), code='invalid'),
})
Наконец, full_clean() проверит все уникальные ограничения вашей модели.
-
Model.validate_unique(exclude=None)[source]
Этот метод похож на clean_fields(), но проверяет все ограничения уникальности вашей модели вместо отдельных значений полей. Необязательный аргумент exclude позволяет указать список имён полей, которые нужно исключить из проверки. Он поднимет исключение ValidationError, если какая-либо проверка полей завершится ошибкой.
Обратите внимание, что если вы передадите аргумент exclude методу validate_unique(), то какое-либо ограничение unique_together, включающее одно из указанных полей, не будет проверено.
Сохранение объектов
Чтобы сохранить объект обратно в базу данных, вызовите save():
-
Model.save(force_insert=False, force_update=False, using=DEFAULT_DB_ALIAS, update_fields=None)[source]
Если вы хотите настроить поведение сохранения, вы можете переопределить этот save() метод. Подробнее см. Переопределение предопределённых методов модели.
Процесс сохранения модели также имеет некоторые тонкости; см. разделы ниже.
Автоинкрементируемые первичные ключи
Если модель имеет AutoField — автоинкрементируемый первичный ключ — то это автоинкрементированное значение будет рассчитано и сохранено как атрибут вашего объекта при первом вызове save():
>>> b2 = Blog(name='Cheddar Talk', tagline='Thoughts on cheese.') >>> b2.id # Returns None, because b doesn't have an ID yet. >>> b2.save() >>> b2.id # Returns the ID of your new object.
Нет способа узнать значение ID до вызова save(), потому что это значение вычисляется вашей базой данных, а не Django.
Для удобства каждая модель имеет AutoField с именем id по умолчанию, если вы не указали явно primary_key=True для поля в вашей модели. Подробнее см. документацию по AutoField.
Свойство pk
-
Model.pk
Независимо от того, определяете ли вы первичный ключ самостоятельно или разрешаете Django предоставить его вам, каждая модель будет иметь свойство pk. Оно ведет себя как обычный атрибут модели, но фактически является псевдонимом для атрибута, являющегося первичным ключом модели. Вы можете читать и устанавливать это значение, как и любой другой атрибут, и это будет обновлять соответствующее поле в модели.
Явное указание значений авто-первичных ключей
Если у модели есть AutoField, но вы хотите явно задать ID нового объекта при сохранении, просто задайте его явно перед сохранением, а не полагайтесь на автоматическое присвоение ID:
>>> b3 = Blog(id=3, name='Cheddar Talk', tagline='Thoughts on cheese.') >>> b3.id # Returns 3. >>> b3.save() >>> b3.id # Returns 3.
Если вы вручную задаёте значения авто-первичных ключей, убедитесь, что не используете уже существующее значение первичного ключа! Если вы создаёте новый объект с явным значением первичного ключа, которое уже существует в базе данных, Django предположит, что вы изменяете существующую запись, а не создаёте новую.
В приведённом выше примере блога этот пример перезапишет предыдущую запись в базе данных:
b4 = Blog(id=3, name='Not Cheddar', tagline='Anything but cheese.') b4.save() # Overrides the previous blog with ID=3!
См. Как Django определяет UPDATE или INSERT ниже, чтобы понять причину этого.
Явное указание значений авто-первичных ключей в основном полезно для массового сохранения объектов, когда вы уверены, что не будет столкновений первичных ключей.
Что происходит при сохранении?
При сохранении объекта Django выполняет следующие шаги:
-
Отправка сигнала pre-save. Сигнал
pre_saveотправляется, позволяя всем функциям, слушающим этот сигнал, выполнить какие-либо действия. -
Предварительная обработка данных. Вызывается метод
pre_save()каждого поля для выполнения любой автоматической модификации данных, которая необходима. Например, поля даты/времени переопределяютpre_save()для реализацииauto_now_addиauto_now. -
Подготовка данных для базы данных. Метод
get_db_prep_save()каждого поля запрашивается, чтобы предоставить его текущее значение в типе данных, который может быть записан в базу данных.Большинству полей не требуется подготовка данных. Простые типы данных, такие как целые числа и строки, «готовы к записи» как объект Python. Однако более сложные типы данных часто требуют некоторой модификации.
Например, поля
DateFieldиспользуют объект Pythondatetimeдля хранения данных. Базы данных не хранят объектыdatetime, поэтому значение поля должно быть преобразовано в строку даты в формате ISO для вставки в базу данных. - Вставка данных в базу данных. Подготовленные данные преобразуются в SQL-запрос для вставки в базу данных.
-
Отправка сигнала post-save. Сигнал
post_saveотправляется, позволяя всем функциям, слушающим этот сигнал, выполнить какие-либо действия.
Как Django определяет UPDATE или INSERT
Вы могли заметить, что объекты базы данных Django используют один и тот же метод save() для создания и изменения объектов. Django абстрагирует необходимость использования INSERT или UPDATE SQL-запросов. В частности, при вызове save(), Django следует этому алгоритму:
- Если атрибут первичного ключа объекта задан в значение, которое оценивается как
True(то есть, значение отличное отNoneили пустая строка), Django выполняетUPDATE. - Если атрибут первичного ключа объекта не задан или если
UPDATEничего не обновил, Django выполняетINSERT.
Единственная тонкость здесь заключается в том, что следует быть осторожным, чтобы не указывать значение первичного ключа явно при сохранении новых объектов, если вы не можете гарантировать, что значение первичного ключа не используется. Подробнее об этом см. Явное указание значений авто-первичных ключей выше и Принудительное выполнение INSERT или UPDATE ниже.
В Django 1.5 и более ранних версиях Django выполнял SELECT при установке атрибута первичного ключа. Если SELECT нашёл строку, тогда Django делал UPDATE, в противном случае он делал INSERT. Старый алгоритм приводит к одному дополнительному запросу в случае UPDATE. Существуют некоторые редкие случаи, когда база данных не сообщает об обновлении строки, даже если база данных содержит строку для значения первичного ключа объекта. Примером является триггер PostgreSQL ON UPDATE, который возвращает NULL. В таких случаях можно вернуться к старому алгоритму, установив опцию select_on_save в значение True.
Принудительное выполнение INSERT или UPDATE
В некоторых редких случаях необходимо заставить метод save() выполнить SQL INSERT и не переходить к выполнению UPDATE. Или наоборот: обновить, если возможно, но не вставлять новую строку. В этих случаях можно передать параметры force_insert=True или force_update=True методу save(). Очевидно, передача обоих параметров является ошибкой: нельзя одновременно вставлять и обновлять.
Встретить необходимость использования этих параметров должно быть очень редко. Django почти всегда сделает всё правильно, и попытка переопределить это приведёт к трудноотслеживаемым ошибкам. Эта функция предназначена только для продвинутых пользователей.
Использование update_fields приведет к принудительному обновлению аналогично force_update.
Обновление атрибутов на основе существующих полей
Иногда вам нужно выполнить простое арифметическое действие над полем, например, увеличить или уменьшить текущее значение. Очевидный способ сделать это — выполнить что-то вроде:
>>> product = Product.objects.get(name='Venezuelan Beaver Cheese') >>> product.number_sold += 1 >>> product.save()
Если старое значение number_sold извлеченное из базы данных, было 10, то значение 11 будет записано обратно в базу данных.
Процесс можно сделать надёжным, избегая гонки, а также немного ускорить, выразив обновление относительно исходного значения поля, а не как явного присвоения нового значения. Django предоставляет F expressions для выполнения такого относительного обновления. Используя F expressions, предыдущий пример записывается так:
>>> from django.db.models import F
>>> product = Product.objects.get(name='Venezuelan Beaver Cheese')
>>> product.number_sold = F('number_sold') + 1
>>> product.save()
Для получения более подробной информации см. документацию по F expressions и их использованию в запросах обновления.
Указание полей для сохранения
Если save() передается список имён полей в ключевом аргументе update_fields, будут обновлены только поля, указанные в этом списке. Это может быть желательно, если вы хотите обновить только одно или несколько полей объекта. Будет незначительный прирост производительности за счёт предотвращения обновления всех полей модели в базе данных. Например:
product.name = 'Name changed again' product.save(update_fields=['name'])
Аргумент update_fields может быть любым итерируемым объектом, содержащим строки. Пустой update_fields итерируемый объект пропустит сохранение. Значение None выполнит обновление всех полей.
Указание update_fields принудительно выполнит обновление.
При сохранении модели, полученной через отложенную загрузку модели (only() или defer()), будут обновлены только поля, загруженные из БД. В этом случае происходит автоматическое update_fields. Если вы присвоите или измените значение любого отложенного поля, поле будет добавлено в обновляемые поля.
Удаление объектов
-
Model.delete(using=DEFAULT_DB_ALIAS, keep_parents=False)[source]
Выполняет SQL DELETE для объекта. Это удаляет объект только в базе данных; экземпляр Python всё ещё будет существовать и содержать данные в своих полях. Этот метод возвращает количество удалённых объектов и словарь с количеством удалений по каждому типу объекта.
Для получения более подробной информации, в том числе о том, как удалять объекты в массовом порядке, см. Удаление объектов.
Если вы хотите настроить поведение удаления, вы можете переопределить метод delete(). Подробнее см. Переопределение предопределённых методов модели.
Иногда при наследовании с несколькими таблицами вам может потребоваться удалить только данные дочерней модели. Указание keep_parents=True сохранит данные родительской модели.
Добавлен параметр keep_parents.
Добавлено возвращаемое значение, описывающее количество удалённых объектов.
Запись объектов в файл
При pickle модели, её текущее состояние сохраняется. При распаковке оно будет содержать экземпляр модели на момент сохранения, а не данные, которые сейчас находятся в базе данных.
Другие методы экземпляров моделей
Несколько методов объектов имеют особые цели.
__str__()
-
Model.__str__()[source]
Метод __str__() вызывается всякий раз, когда вы вызываете str() над объектом. Django использует str(obj) в ряде мест. В первую очередь, для отображения объекта в админской панели Django и в качестве значения, вставленного в шаблон при отображении объекта. Таким образом, вы всегда должны возвращать приятное, удобочитаемое представление модели из метода __str__().
Например:
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible # only if you need to support Python 2
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)
Если вам нужна совместимость с Python 2, вы можете украсить свой класс модели декоратором python_2_unicode_compatible(), как показано выше.
__eq__()
-
Model.__eq__()[source]
Метод равенства определён таким образом, что экземпляры с одинаковым значением первичного ключа и тем же классом считаются равными, за исключением экземпляров с значением первичного ключа None, которые не равны ничему, кроме себя. Для моделей-прокси конкретным классом является родительская модель, не являющаяся прокси-моделью; для всех остальных моделей это просто класс модели.
Например:
from django.db import models
class MyModel(models.Model):
id = models.AutoField(primary_key=True)
class MyProxyModel(MyModel):
class Meta:
proxy = True
class MultitableInherited(MyModel):
pass
# Primary keys compared
MyModel(id=1) == MyModel(id=1)
MyModel(id=1) != MyModel(id=2)
# Primay keys are None
MyModel(id=None) != MyModel(id=None)
# Same instance
instance = MyModel(id=None)
instance == instance
# Proxy model
MyModel(id=1) == MyProxyModel(id=1)
# Multi-table inheritance
MyModel(id=1) != MultitableInherited(id=1)
__hash__()
-
Model.__hash__()[source]
Метод __hash__() основан на значении первичного ключа экземпляра. Он фактически hash(obj.pk). Если у экземпляра нет значения первичного ключа, будет поднято TypeError (в противном случае метод __hash__() возвращал бы разные значения до и после сохранения экземпляра, но изменение значения __hash__() экземпляра запрещено в Python.
get_absolute_url()
-
Model.get_absolute_url()
Определите метод get_absolute_url() , чтобы указать Django, как вычислять каноническую URL для объекта. Для вызывающих сторон этот метод должен возвращать строку, которую можно использовать для обращения к объекту по протоколу HTTP.
Например:
def get_absolute_url(self):
return "/people/%i/" % self.id
Хотя этот код правильный и простой, это может быть не самый переносимый способ написания такого метода. Функция reverse() обычно является лучшим подходом.
Например:
def get_absolute_url(self):
from django.urls import reverse
return reverse('people.views.details', args=[str(self.id)])
Одно из мест, где Django использует get_absolute_url() , — в приложении администрирования. Если объект определяет этот метод, страница редактирования объекта будет иметь ссылку «Просмотр на сайте», которая переведёт вас непосредственно на общедоступную страницу объекта, как указано в get_absolute_url().
Аналогично, несколько других компонентов Django, таких как фреймворк для лент новостей, используют get_absolute_url() при его определении. Если для экземпляров вашей модели имеет смысл иметь уникальную URL, вы должны определить get_absolute_url().
Предупреждение
Следует избегать построения URL на основе невалидированных данных пользователя, чтобы уменьшить вероятность подмены ссылок или перенаправлений:
def get_absolute_url(self):
return '/%s/' % self.name
Если self.name '/example.com', это возвращает '//example.com/', что, в свою очередь, является допустимой схемой относительной URL, но не ожидаемой '/%2Fexample.com/'.
Хорошей практикой является использование get_absolute_url() в шаблонах вместо жёсткой кодировки URL объектов. Например, этот шаблонный код плохой:
<!-- BAD template code. Avoid! -->
<a href="/people/{{ object.id }}/">{{ object.name }}</a>
Этот шаблонный код намного лучше:
<a href="{{ object.get_absolute_url }}">{{ object.name }}</a>
Логика здесь заключается в том, что если вы измените структуру URL ваших объектов, даже для чего-то простого, например, исправления ошибки в написании, вам не придётся отслеживать каждое место, где URL может быть создан. Укажите его один раз в get_absolute_url() и заставьте весь остальной код вызывать это единственное место.
Примечание
Строка, возвращаемая из get_absolute_url(), должна содержать только символы ASCII (требуется спецификацией URI, RFC 2396) и быть закодированной в URL, при необходимости.
Код и шаблоны, вызывающие get_absolute_url(), должны иметь возможность использовать результат напрямую без дальнейшей обработки. Вы можете использовать функцию django.utils.encoding.iri_to_uri(), чтобы помочь с этим, если вы используете строковые значения Unicode, содержащие символы за пределами диапазона ASCII.
Дополнительные методы экземпляра
В дополнение к save(), delete(), объект модели может иметь некоторые из следующих методов:
-
Model.get_FOO_display()
Для каждого поля, для которого установлено choices, у объекта будет метод get_FOO_display(), где FOO — имя поля. Этот метод возвращает «человекопонятное» значение поля.
Например:
from django.db import models
class Person(models.Model):
SHIRT_SIZES = (
('S', 'Small'),
('M', 'Medium'),
('L', 'Large'),
)
name = models.CharField(max_length=60)
shirt_size = models.CharField(max_length=2, choices=SHIRT_SIZES)
>>> p = Person(name="Fred Flintstone", shirt_size="L") >>> p.save() >>> p.shirt_size 'L' >>> p.get_shirt_size_display() 'Large'
-
Model.get_next_by_FOO(**kwargs)
-
Model.get_previous_by_FOO(**kwargs)
Для каждого DateField и DateTimeField, у которых не установлено null=True, у объекта будут методы get_next_by_FOO() и get_previous_by_FOO(), где FOO — имя поля. Это возвращает следующий и предыдущий объект относительно поля даты, вызывая исключение DoesNotExist при необходимости.
Оба этих метода будут выполнять свои запросы, используя менеджер по умолчанию для модели. Если вам нужно имитировать фильтрацию, используемую пользовательским менеджером, или выполнить разовый пользовательский фильтр, оба метода также принимают необязательные ключевые аргументы, которые должны быть в формате, описанном в Поисковых операциях по полям.
Обратите внимание, что в случае одинаковых значений даты эти методы будут использовать первичный ключ в качестве решающего фактора. Это гарантирует, что никакие записи не пропускаются и не дублируются. Это также означает, что вы не можете использовать эти методы для несохранённых объектов.
Другие атрибуты
DoesNotExist
-
exception Model.DoesNotExist -
Это исключение генерируется ORM в нескольких местах, например,
QuerySet.get(), когда объект не найден для заданных параметров запроса.Django предоставляет исключение
DoesNotExistв качестве атрибута каждого класса модели, чтобы определить класс объекта, который не был найден, и позволить вам поймать конкретный класс модели с помощьюtry/except. Исключение является подклассомdjango.core.exceptions.ObjectDoesNotExist.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/1.10/ref/models/instances/