Ссылка на связанные объекты ¶
-
класс
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 = Нет , ** 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 понимает, чтоblog
новому полю объектаEntry
должно быть присвоено значение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
ForeignKey
blog
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
when,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()
стереть кэш поджимать.