Справочник по связанным объектам
-
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.
-
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/5.0/ref/models/relations/