Ссылка на связанные объекты
-
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/3.0/ref/models/relations/