Ссылка на связанные объекты
-
class RelatedManager -
«Менеджер связанных объектов» — это менеджер, используемый в контексте отношений один-ко-многим или многие-ко-многим. Это происходит в двух случаях:
-
«Другая сторона» отношения
ForeignKey. То есть:from django.db import models class Reporter(models.Model): # ... pass class Article(models.Model): reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)В приведённом выше примере методы ниже будут доступны в менеджере
reporter.article_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и они будут вызваны один раз до создания любого промежуточного экземпляра(ов).Изменено в Django 3.1:Значения аргумента
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.Изменено в Django 3.1:Значения аргумента
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и они будут вызваны один раз до создания любого промежуточного экземпляра(ов).Изменено в Django 3.1:Значения аргумента
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/3.1/ref/models/relations/