Ссылка на экземпляр модели
В этом документе описаны подробности API Model. Он опирается на материал, представленный в руководствах по моделям и запросам к базе данных, поэтому, вероятно, вам следует прочитать и понять эти документы перед тем, как читать этот.
В этом справочнике мы будем использовать примеры моделей веб-журнала, представленные в руководстве по запросам к базе данных.
Создание объектов
Для создания нового экземпляра модели создайте его, как любой другой класс Python:
-
class Model(**kwargs)
Ключевые аргументы — это имена полей, которые вы определили в своей модели. Обратите внимание, что создание экземпляра модели никак не затрагивает вашу базу данных; для этого вам нужно 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)
Метод 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)
Если вам нужно перезагрузить значения модели из базы данных, вы можете использовать метод 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()
Вспомогательный метод, возвращающий набор имен атрибутов всех полей, которые в настоящее время отложены для этой модели.
Проверка объектов
Проверка модели включает три этапа:
- Проверка полей модели -
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)
Этот метод вызывает 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)
Этот метод проверит все поля вашей модели. Необязательный аргумент exclude позволяет указать список имен полей, которые нужно исключить из проверки. Он сгенерирует исключение ValidationError, если какое-либо поле не пройдет проверку.
Второй шаг full_clean() — вызов Model.clean(). Этот метод должен быть переопределён для выполнения пользовательской проверки вашей модели.
-
Model.clean()
Этот метод должен использоваться для предоставления пользовательской проверки модели и для изменения атрибутов вашей модели, если это необходимо. Например, вы можете использовать его для автоматического предоставления значения для поля или для проверки, которая требует доступа к более чем одному полю:
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)
Этот метод похож на 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)
Если вы хотите настроить поведение сохранения, вы можете переопределить этот save() метод. Более подробную информацию см. в разделе Переопределение предопределённых методов модели.
Процесс сохранения модели также имеет некоторые тонкости; см. разделы ниже.
Автоинкрементируемые первичные ключи
Если модель имеет AutoField — автоинкрементируемый первичный ключ — то это значение автоинкремента будет вычислено и сохранено как атрибут вашего объекта при первом вызове save():
>>> b2 = Blog(name='Cheddar Talk', tagline='Thoughts on cheese.') >>> b2.id # Returns None, because b2 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, но вы хотите явно определить ID нового объекта при сохранении, задайте его явно перед сохранением, а не полагайтесь на автоматическое присвоение ID:
>>> 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() и атрибут первичного ключа объекта не определяет default, Django следует этому алгоритму:
- Если атрибут первичного ключа объекта задан на значение, которое оценивается как
True(т.е., значение отличное отNoneили пустой строки), Django выполняетUPDATE. - Если атрибут первичного ключа объекта не задан или если
UPDATEничего не обновил (например, если первичный ключ установлен на значение, которого нет в базе данных), Django выполняетINSERT.
Если атрибут первичного ключа объекта определяет default, то Django выполняет UPDATE , если это существующий экземпляр модели и первичный ключ установлен на значение, которое существует в базе данных. В противном случае Django выполняет INSERT.
Единственная тонкость заключается в том, что следует быть осторожным, не указывать явно значение первичного ключа при сохранении новых объектов, если вы не можете гарантировать, что значение первичного ключа не используется. Более подробную информацию об этом нюансе см. в разделах Явное указание значений автоинкрементируемого первичного ключа выше и Принудительное выполнение INSERT или UPDATE ниже.
В Django 1.5 и ранее Django выполнял SELECT при установке атрибута первичного ключа. Если SELECT находил строку, то Django выполнял UPDATE, в противном случае — INSERT. Старый алгоритм приводит к одной дополнительной запросу в случае UPDATE. Существуют редкие случаи, когда база данных не сообщает об обновлении строки, даже если база данных содержит строку для значения первичного ключа объекта. Примером является триггер PostgreSQL ON UPDATE, который возвращает NULL. В таких случаях можно вернуться к старому алгоритму, установив опцию select_on_save в значение True.
Model.save() больше не пытается найти строку при сохранении нового объекта Model и предоставлении значения по умолчанию для первичного ключа и всегда выполняет INSERT.
Принудительное выполнение INSERT или UPDATE
В некоторых редких случаях необходимо принудить метод save() выполнить SQL-операцию INSERT и не использовать UPDATE. Или наоборот: обновить, если возможно, но не вставлять новую строку. В этих случаях можно передать параметры force_insert=True или force_update=True методу save(). Передача обоих параметров является ошибкой: нельзя одновременно выполнить вставку и обновление!
В большинстве случаев вам не нужно использовать эти параметры. Django почти всегда делает правильный выбор, и попытка переопределить его может привести к ошибкам, которые сложно отследить. Эта функция предназначена только для продвинутого использования.
Использование update_fields приведет к принудительному обновлению аналогично force_update.
Обновление атрибутов на основе существующих полей
Иногда вам нужно выполнить простое арифметическое действие над полем, например, инкрементировать или декрементировать текущее значение. Один из способов достижения этого — выполнение арифметики на Python, например:
>>> 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)
Выполняет SQL-операцию DELETE для объекта. Это удаляет объект только из базы данных; экземпляр Python по-прежнему будет существовать и содержать данные в своих полях. Этот метод возвращает количество удаленных объектов и словарь с количеством удалений по типу объекта.
Дополнительную информацию, включая то, как удалить объекты в пакетном режиме, см. в Удаление объектов.
Если вы хотите настроить поведение удаления, вы можете переопределить метод delete(). Дополнительную информацию см. в Переопределение предопределенных методов модели.
Иногда при наследовании с несколькими таблицами вы можете захотеть удалить только данные дочерней модели. Указание keep_parents=True сохранит данные родительской модели.
Сериализация объектов
При сериализации модели с помощью pickle сохраняется ее текущее состояние. При десериализации она будет содержать экземпляр модели на момент сериализации, а не данные, которые есть сейчас в базе данных.
Другие методы экземпляра модели
Некоторые методы объекта имеют специальное назначение.
__str__()
-
Model.__str__()
Метод __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__()
Метод равенства определен таким образом, что экземпляры с одинаковым значением первичного ключа и одинаковым конкретным классом считаются равными, за исключением того, что экземпляры с значением первичного ключа 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__()
Метод __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#section-2) и быть закодированной по 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'
Добавлена поддержка ArrayField и RangeField.
-
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 при необходимости.
Оба этих метода будут выполнять свои запросы с использованием менеджера по умолчанию для модели. Если вам нужно эмулировать фильтрацию, используемую пользовательским менеджером, или выполнить одноразовую пользовательскую фильтрацию, оба метода также принимают необязательные ключевые аргументы, которые должны быть в формате, описанном в Поисках по полям.
Обратите внимание, что в случае одинаковых значений даты эти методы будут использовать первичный ключ в качестве разрыва. Это гарантирует, что никакие записи не будут пропущены или дублированы. Это также означает, что вы не можете использовать эти методы для несохраненных объектов.
Переопределение дополнительных методов экземпляра
В большинстве случаев переопределение или наследование get_FOO_display(), get_next_by_FOO(), и get_previous_by_FOO() должно работать как ожидается. Однако, поскольку они добавляются метаклассом, непрактично учитывать все возможные структуры наследования. В более сложных случаях вы должны переопределить Field.contribute_to_class() для задания необходимых методов.
Другие атрибуты
_state
-
Model._state -
Атрибут
_stateотносится к объектуModelState, который отслеживает жизненный цикл экземпляра модели.Объект
ModelStateимеет два атрибута:adding, флаг, которыйTrue, если модель ещё не сохранена в базе данных, иdb, строка, указывающая на алиас базы данных, из которой был загружен или в которую был сохранён экземпляр.У вновь созданных экземпляров
adding=Trueиdb=Noneустановлены, так как они ещё не сохранены. У экземпляров, извлечённых изQuerySet, установленыadding=Falseиdbв значение алиаса соответствующей базы данных.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/3.1/ref/models/instances/