Ссылка на экземпляр модели
В этом документе описываются детали 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().
Обновление объектов из базы данных
Если вы удаляете поле из экземпляра модели, повторный доступ к нему перезагружает значение из базы данных:
>>> obj = MyModel.objects.first() >>> del obj.field >>> obj.field # Loads the field from the database
-
Model.refresh_from_db(using=None, fields=None)[source]
Если вам нужно перезагрузить значения модели из базы данных, вы можете использовать метод refresh_from_db(). При вызове этого метода без аргументов выполняется следующее:
- Все неотложенные поля модели обновляются до значений, которые в данный момент присутствуют в базе данных.
- Любые кэшированные отношения очищаются из перезагруженного экземпляра.
Перезагрузка происходит только из полей модели. Другие зависящие от базы данных значения, такие как аннотации, не перезагружаются. Любые атрибуты @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().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 gettext_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 NON_FIELD_ERRORS, ValidationError
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() проверит все уникальные ограничения вашей модели.
Как вызвать ошибки валидации для конкретных полей, если эти поля не отображаются в форме ModelForm
Вы не можете вызвать ошибки валидации в Model.clean() для полей, которые не отображаются в форме модели (форма может ограничивать свои поля с помощью Meta.fields или Meta.exclude). Это приведет к ошибке ValueError, потому что ошибка валидации не сможет быть связана со скрытым полем.
Чтобы обойти эту проблему, переопределите Model.clean_fields(), так как она получает список полей, исключенных из валидации. Например:
class Article(models.Model):
...
def clean_fields(self, exclude=None):
super().clean_fields(exclude=exclude)
if self.status == 'draft' and self.pub_date is not None:
if exclude and 'status' in exclude:
raise ValidationError(
_('Draft entries may not have a publication date.')
)
else:
raise ValidationError({
'status': _(
'Set status to draft if there is not a '
'publication date.'
),
})
-
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.
Нет способа узнать значение идентификатора до вызова save(), так как это значение вычисляется вашей базой данных, а не Django.
Для удобства каждая модель имеет AutoField с именем id по умолчанию, если вы явно не указали primary_key=True в поле вашей модели. Более подробную информацию см. в документации для AutoField.
Свойство pk
-
Model.pk
Независимо от того, определяете ли вы первичный ключ самостоятельно или позволяете Django предоставить его, каждая модель будет иметь свойство pk. Оно ведет себя как обычный атрибут модели, но на самом деле является псевдонимом для поля, которое является первичным ключом модели. Вы можете читать и изменять это значение, как и любой другой атрибут, и это обновит соответствующее поле в модели.
Явное указание значений автоинкрементируемых первичных ключей
Если у модели есть AutoField, но вы хотите явно задать идентификатор нового объекта при сохранении, просто задайте его явно перед сохранением, а не полагайтесь на автоматическое назначение идентификатора:
>>> 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 ниже, чтобы понять, почему это происходит.
Явное указание значений автоинкрементируемых первичных ключей в основном полезно для массового сохранения объектов, когда вы уверены, что столкновений по первичным ключам не будет.
Если вы используете PostgreSQL, последовательность, связанную с первичным ключом, может потребоваться обновить; см. Ручное указание значений автоинкрементируемых первичных ключей.
Что происходит при сохранении?
Когда вы сохраняете объект, 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 абстрагирует необходимость использования операторов SQL INSERT или UPDATE. В частности, при вызове 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 сохранит данные родительской модели.
Сериализация объектов
При pickle модели её текущее состояние сериализуется. При разасериализации она будет содержать экземпляр модели на момент сериализации, а не данные, которые в настоящее время находятся в базе данных.
Другие методы экземпляра модели
Несколько методов объекта имеют специальные цели.
__str__()
-
Model.__str__()[source]
Метод __str__() вызывается всякий раз, когда вы вызываете str() для объекта. Django использует str(obj) во многих местах. В частности, для отображения объекта в административной панели Django и в качестве значения, вставляемого в шаблон, когда он отображает объект. Поэтому вы всегда должны возвращать удобочитаемое представление модели из метода __str__().
Например:
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)
__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)
# Primary 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(), чтобы помочь в этом, если вы используете строки, содержащие символы, не входящие в диапазон 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/2.1/ref/models/instances/