Ссылка на связанные объекты
-
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. -
Обе стороны
ManyToManyFieldсвязи:class Topping(models.Model): # ... pass class Pizza(models.Model): toppings = models.ManyToManyField(Topping)В этом примере методы ниже будут доступны как для
topping.pizza_set, так и дляpizza.toppings.
-
add(*objs, bulk=True, through_defaults=None) -
Добавляет указанные объекты модели в набор связанных объектов.
Пример:
>>> 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) -
Создает новый объект, сохраняет его и помещает в набор связанных объектов. Возвращает только что созданный объект:
>>> 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) -
Удаляет указанные объекты модели из набора связанных объектов:
>>> 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) -
Удаляет все объекты из набора связанных объектов:
>>> 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) -
Заменяет набор связанных объектов:
>>> 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(),create(),remove(),clear(), иset()немедленно применяют изменения в базе данных для всех типов связанных полей. Другими словами, нет необходимости вызыватьsave()на любом конце связи.Если вы используете
prefetch_related(), методыadd(),remove(),clear(), иset()очищают кэш предварительной выборки. -
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/4.0/ref/models/relations/