Ссылка на экземпляр модели
В данном документе описываются подробности API Model. Он опирается на материал, представленный в руководствах по моделям и запросам к базе данных, поэтому вам, вероятно, стоит прочитать и понять эти документы перед чтением этого.
В этом справочнике мы будем использовать примеры моделей веб-журнала, представленные в руководстве по запросам к базе данных.
Создание объектов
Чтобы создать новый экземпляр модели, просто создайте его, как любой другой класс 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(). При вызове этого метода без аргументов выполняется следующее:
- Все неотложенные поля модели обновляются до значений, присутствующих в настоящее время в базе данных.
- Предыдущие загруженные связанные экземпляры, для которых значение отношения больше недействительно, удаляются из перезагруженного экземпляра. Например, если у вас есть внешний ключ от перезагруженного экземпляра к другой модели с именем
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().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 предположит, что вы изменяете существующую запись, а не создаете новую.
В примере блога 'Cheddar Talk', данный пример переопределит предыдущую запись в базе данных:
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 абстрагирует необходимость использования 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 сохранит данные родительской модели.
Сериализация объектов
При 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)
# 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() , — это приложение admin. Если объект определяет этот метод, страница редактирования объекта будет иметь ссылку «Просмотреть на сайте», которая переведёт вас непосредственно к общедоступному представлению объекта, как указано в 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.0/ref/models/instances/