Справочник связанных объектов
-
class RelatedManager -
«Менеджер связанной модели» — это менеджер, используемый в контексте связи «один-ко-многим» или «многие-ко-многим». Это происходит в двух случаях:
-
«Другая сторона» отношения
ForeignKey. То есть:from django.db import models class Blog(models.Model): # ... pass class Entry(models.Model): blog = models.ForeignKey(Blog, on_delete=models.CASCADE, null=True)В приведённом выше примере указанные ниже методы будут доступны в менеджере
blog.entry_set. -
Обе стороны отношения
ManyToManyFieldclass Topping(models.Model): # ... pass class Pizza(models.Model): toppings = models.ManyToManyField(Topping)В этом примере указанные ниже методы будут доступны и в
topping.pizza_set, и вpizza.toppings.
-
add(*objs, bulk=True, through_defaults=None)
-
aadd(*objs, bulk=True, through_defaults=None) -
Асинхронная версия:
aaddДобавляет указанные объекты модели в набор связанных объектов.
Пример:
>>> b = Blog.objects.get(id=1) >>> e = Entry.objects.get(id=234) >>> b.entry_set.add(e) # Associates Entry e with Blog b.
В приведённом выше примере для отношения
ForeignKeyдля выполнения обновления используетсяQuerySet.update(). Для этого объекты уже должны быть сохранены.Вместо этого можно использовать аргумент
bulk=False, чтобы поручить связанному менеджеру выполнить обновление вызовомe.save().Однако при использовании
add()со связью «многие-ко-многим» никакие методыsave()не вызываются (аргументbulkне существует); связи создаются с помощьюQuerySet.bulk_create(). Если при создании связи требуется выполнить пользовательскую логику, подпишитесь на сигналm2m_changed, который вызовет действияpre_addиpost_add.Вызов
add()для уже существующей связи не создаст дубликат, но сигналы всё равно будут отправлены.Для связей «многие-ко-многим» метод
add()принимает в качестве аргумента*objsкак экземпляры модели, так и значения полей, обычно первичные ключи.При необходимости используйте аргумент
through_defaults, чтобы указать значения для новых экземпляров промежуточной модели. В словареthrough_defaultsможно использовать вызываемые объекты в качестве значений: они будут вызваны один раз перед созданием любых экземпляров промежуточной модели.
-
create(through_defaults=None, **kwargs)
-
acreate(through_defaults=None, **kwargs) -
Асинхронная версия:
acreateСоздаёт новый объект, сохраняет его и добавляет в набор связанных объектов. Возвращает только что созданный объект:
>>> b = Blog.objects.get(id=1) >>> e = b.entry_set.create( ... headline="Hello", body_text="Hi", pub_date=datetime.date(2005, 1, 1) ... ) # No need to call e.save() at this point -- it's already been saved.
Это эквивалентно следующему (но проще):
>>> b = Blog.objects.get(id=1) >>> e = Entry(blog=b, headline="Hello", body_text="Hi", pub_date=datetime.date(2005, 1, 1)) >>> e.save(force_insert=True)
Обратите внимание: не нужно указывать именованный аргумент модели, определяющий связь. В приведённом выше примере мы не передаём параметр
blogметодуcreate(). Django определяет, что для поляblogнового объектаEntryследует задать значениеb.При необходимости используйте аргумент
through_defaults, чтобы указать значения для нового экземпляра промежуточной модели. В словареthrough_defaultsможно использовать вызываемые объекты в качестве значений.
-
remove(*objs, bulk=True)
-
aremove(*objs, bulk=True) -
Асинхронная версия:
aremoveУдаляет указанные объекты модели из набора связанных объектов:
>>> b = Blog.objects.get(id=1) >>> e = Entry.objects.get(id=234) >>> b.entry_set.remove(e) # Disassociates Entry e from Blog b.
Как и в случае с
add(), в приведённом выше примере для выполнения обновления вызываетсяe.save(). Однако при использованииremove()со связью «многие-ко-многим» связи удаляются с помощьюQuerySet.delete(), то есть методыsave()модели не вызываются; если при удалении связи требуется выполнить пользовательский код, подпишитесь на сигналm2m_changed.Для связей «многие-ко-многим» метод
remove()принимает в качестве аргумента*objsкак экземпляры модели, так и значения полей, обычно первичные ключи.Для объектов
ForeignKeyэтот метод существует только при условииnull=True. Если для связанного поля нельзя задать значениеNone(NULL), объект нельзя удалить из связи, не добавив его в другую. В приведённом выше примере удалениеeизb.entry_set()эквивалентно выполнениюe.blog = None, что недопустимо, поскольку уblogForeignKeyотсутствуетnull=True.Для объектов
ForeignKeyэтот метод принимает аргументbulk, определяющий способ выполнения операции. Если заданоTrue(по умолчанию), используетсяQuerySet.update(). Если заданоbulk=False, вместо этого вызывается методsave()каждого отдельного экземпляра модели. Это вызывает сигналыpre_saveиpost_saveи снижает производительность.Для связей «многие-ко-многим» именованный аргумент
bulkне существует.
-
clear(bulk=True)
-
aclear(bulk=True) -
Асинхронная версия:
aclearУдаляет все объекты из набора связанных объектов:
>>> b = Blog.objects.get(id=1) >>> b.entry_set.clear()
Обратите внимание: связанные объекты не удаляются — они лишь отвязываются.
Как и
remove(), методclear()доступен только для объектовForeignKey, если выполняется условиеnull=True; он также принимает именованный аргументbulk.Для связей «многие-ко-многим» именованный аргумент
bulkне существует.
-
set(objs, bulk=True, clear=False, through_defaults=None)
-
aset(objs, bulk=True, clear=False, through_defaults=None) -
Асинхронная версия:
asetЗаменяет набор связанных объектов:
>>> new_list = [obj1, obj2, obj3] >>> e.related_set.set(new_list)
Этот метод принимает аргумент
clear, определяющий способ выполнения операции. Если заданоFalse(по умолчанию), элементы, отсутствующие в новом наборе, удаляются с помощьюremove(), а добавляются только новые элементы. Если заданоclear=True, вместо этого вызывается методclear(), и весь набор добавляется за один раз.Для объектов
ForeignKeyаргументbulkпередаётся в методыadd()иremove().Для связей «многие-ко-многим» именованный аргумент
bulkне существует.Обратите внимание: поскольку
set()— составная операция, при её выполнении возможны состояния гонки. Например, между вызовамиclear()иadd()в базу данных могут быть добавлены новые объекты.Для связей «многие-ко-многим» метод
set()принимает в качестве аргументаobjsсписок экземпляров модели или значений полей, обычно первичных ключей.При необходимости используйте аргумент
through_defaults, чтобы указать значения для новых экземпляров промежуточной модели. В словареthrough_defaultsможно использовать вызываемые объекты в качестве значений: они будут вызваны один раз перед созданием любых экземпляров промежуточной модели.
Примечание
Обратите внимание:
add(),aadd(),create(),acreate(),remove(),aremove(),clear(),aclear(),set()иaset()немедленно применяют изменения в базе данных для всех типов связанных полей. Иными словами, вызыватьsave()/asave()на любой стороне отношения не нужно.Если вы используете
prefetch_related(), методыadd(),aadd(),remove(),aremove(),clear(),aclear(),set()иaset()очищают предварительно загруженный кэш. -
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/6.0/ref/models/relations/