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