Справочник по связанным объектам
-
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) -
Добавляет указанные объекты модели в набор связанных объектов.
Пример:
>>> 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()для уже существующего отношения не продублирует его, но все равно запустит сигналы.
-
create(**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.
-
remove(*objs) -
Удаляет указанные объекты модели из набора связанных объектов:
>>> 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, если вы хотите выполнить пользовательский код при удалении отношения.Для объектов
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и происходит за счет производительности.
-
clear() -
Удаляет все объекты из набора связанных объектов:
>>> b = Blog.objects.get(id=1) >>> b.entry_set.clear()
Обратите внимание, что это не удаляет связанные объекты — это просто отсоединяет их.
Точно так же, как
remove(),clear()доступно только дляForeignKey, гдеnull=True, и оно также принимает ключевой аргументbulk.
-
set(objs, bulk=True, clear=False) -
Заменяет набор связанных объектов:
>>> new_list = [obj1, obj2, obj3] >>> e.related_set.set(new_list)
Этот метод принимает аргумент
clearдля управления способом выполнения операции. ЕслиFalse(по умолчанию), отсутствующие элементы из нового набора удаляются с помощьюremove(), а новые добавляются. Еслиclear=True, вместо этого вызывается методclear(), и весь набор добавляется сразу.Аргумент
bulkпередаётся вadd().Обратите внимание, что поскольку
set()— это сложная операция, она подвержена проблемам гонок. Например, новые объекты могут быть добавлены в базу данных между вызовомclear()и вызовомadd().
Примечание
Обратите внимание, что
add(),create(),remove(),clear(), иset()все сразу же применяют изменения в базе данных для всех типов связанных полей. Другими словами, нет необходимости вызыватьsave()с любой стороны отношения.Также, если вы используете промежуточную модель для отношения «многие ко многим», то методы
add(),create(),remove(), иset()отключены.Если вы используете
prefetch_related(), то методыadd(),remove(),clear(), иset()очищают кэш предварительной выборки.Изменено в Django 1.11:Было добавлено очищение кэша предварительной выборки, описанное выше.
-
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/2.0/ref/models/relations/