Ссылка на связанные объекты
-
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, и они будут вычислены один раз перед созданием каких-либо промежуточных экземпляров.Изменено в Django 4.2:aadd()метод был добавлен.
-
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.Изменено в Django 4.1:acreate()метод был добавлен.
-
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отсутствует.Изменено в Django 4.2:aremove()метод был добавлен.
-
clear(bulk=True)
-
aclear(bulk=True) -
Асинхронный вариант:
aclearУдаляет все объекты из набора связанных объектов:
>>> b = Blog.objects.get(id=1) >>> b.entry_set.clear()
Обратите внимание, что это не удаляет связанные объекты — это просто отвязывает их.
Так же как и
remove(),clear()доступен только дляForeignKey, гдеnull=True, и также принимает ключевой аргументbulk.Для отношений «многие ко многим» ключевой аргумент
bulkотсутствует.Изменено в Django 4.2:aclear()метод был добавлен.
-
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и они будут вычислены один раз перед созданием каких-либо промежуточных экземпляров.Изменено в Django 4.2:aset()метод был добавлен.
-
Примечание
Обратите внимание, что
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/4.2/ref/models/relations/