Ссылка на связанные объекты
-
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 определяет, что полеEntryнового объектаblogдолжно быть установлено в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/5.1/ref/models/relations/