Ссылка на экземпляр модели
В этом документе описаны подробности 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, поэтому можно использовать cls(**(zip(field_names, values))) для инициализации объекта. Если все поля модели присутствуют, то values гарантированно находятся в порядке, ожидаемом __init__(). То есть экземпляр можно создать с помощью cls(*values). Проверить, присутствуют ли все поля, можно, обратившись к cls._deferred. Если False, то все поля были загружены из базы данных.
В дополнение к созданию новой модели, метод from_db() должен установить флаги adding и db в атрибуте _state нового экземпляра.
Ниже приведен пример того, как записывать начальные значения полей, загружаемых из базы данных:
@classmethod
def from_db(cls, db, field_names, values):
# default implementation of from_db() (could be replaced
# with super())
if cls._deferred:
instance = cls(**zip(field_names, values))
else:
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().
Обновление объектов из базы данных
-
Model.refresh_from_db(using=None, fields=None, **kwargs)[source]
Если вам нужно перезагрузить значения модели из базы данных, вы можете использовать метод refresh_from_db(). Когда этот метод вызывается без аргументов, выполняется следующее:
- Все поля модели, не отложенные (non-deferred), обновляются до значений, которые в настоящее время присутствуют в базе данных.
- Ранее загруженные связанные экземпляры, для которых значение отношения больше недействительно, удаляются из перезагруженного экземпляра. Например, если у вас есть внешний ключ от перезагруженного экземпляра к другой модели с именем
Author, то еслиobj.author_id != obj.author.id,obj.authorбудут удалены, и при следующем доступе они будут перезагружены со значениемobj.author_id.
Обратите внимание, что из базы данных перезагружаются только поля модели. Другие зависящие от базы данных значения, такие как аннотации, не перезагружаются.
Перезагрузка происходит из базы данных, из которой был загружен экземпляр, или из базы данных по умолчанию, если экземпляр не был загружен из базы данных. Аргумент 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.
Нет способа узнать значение идентификатора до вызова 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 ниже, чтобы понять причину этого.
Явное указание значений автопервичного ключа в основном полезно для массового сохранения объектов, когда вы уверены, что столкновения первичных ключей не произойдут.
Что происходит при сохранении?
При сохранении объекта Django выполняет следующие действия:
-
Отправить сигнал pre-save. Сигнал сигнала
django.db.models.signals.pre_saveотправляется, позволяя любым функциям, которые прослушивают этот сигнал, выполнить некоторые настраиваемые действия. -
Предварительная обработка данных. Каждое поле объекта запрашивает выполнение автоматической модификации данных, если это необходимо для поля.
Большинство полей не выполняют предварительной обработки — данные поля сохраняются без изменений. Предварительная обработка используется только для полей со специальным поведением. Например, если ваша модель имеет
DateFieldсauto_now=True, на этапе предварительной обработки данные в объекте будут изменены для обеспечения того, что поле даты содержит текущую дату. (В нашей документации пока нет списка всех полей со «специальным поведением»). -
Подготовка данных для базы данных. Каждому полю задается предоставление текущего значения в формате данных, который может быть записан в базу данных.
Большинству полей не требуется подготовка данных. Простые типы данных, такие как целые числа и строки, «готовы к записи» в виде объекта Python. Однако более сложные типы данных часто требуют некоторой модификации.
Например, поля
DateFieldиспользуют объект Pythondatetimeдля хранения данных. Базы данных не хранят объектыdatetime, поэтому значение поля должно быть преобразовано в строку даты в формате ISO для вставки в базу данных. - Вставка данных в базу данных. Подготовленные данные затем формируются в SQL-запрос для вставки в базу данных.
-
Отправить сигнал post-save. Сигнал
django.db.models.signals.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]
Метод равенства определён таким образом, что экземпляры с одинаковым значением первичного ключа и одним и тем же конкретным классом считаются равными. Для прокси-моделей конкретным классом является первая не-прокси-родительская модель; для всех остальных моделей это просто класс модели.
Например:
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
MyModel(id=1) == MyModel(id=1)
MyModel(id=1) == MyProxyModel(id=1)
MyModel(id=1) != MultitableInherited(id=1)
MyModel(id=1) != MyModel(id=2)
__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.core.urlresolvers 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.9/ref/models/instances/