Ссылка на связанные объекты
-
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, и они будут вычислены один раз перед созданием любого промежуточного экземпляра.Изменено в 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.2/ref/models/relations/