Справочник по связям между объектами¶
-
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
, и они будут вычисляться один раз перед созданием любого промежуточного экземпляра(ов).Changed in 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 выясняет, что в полеblog
нового объектаEntry
следует установить значениеb
.При необходимости используйте аргумент
through_defaults
, чтобы указать значения для нового экземпляра промежуточной модели. Вы можете использовать вызываемые объекты как значения в словареthrough_defaults
.Changed in 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
, и потому чтоblog
ForeignKey
не имеетnull=True
, это недопустимо.Для объектов
ForeignKey
этот метод принимает аргументобъемный
для управления тем, как выполнять операцию. Если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
, и они будут вычисляться один раз перед созданием любого промежуточного экземпляра(ов).Changed in Django 3.1:Значения
through_defaults
теперь могут быть вызываемыми.
Примечание
Обратите внимание, что
add()
,create()
,remove()
,clear()
иset()
немедленно применяют изменения базы данных для всех типов связанных полей. Другими словами, нет необходимости вызыватьsave()
на любом конце отношения.Если вы используете
prefetch_related()
,add()
,remove()
,clear()
иset()
очищают предварительно загруженный кеш.
Django 3.2
Содержание
Дополнительно
Вы здесь:
-
Документация Django Django 3.2
- Справочник по API
- Модели
- Справочник по связям между объектами
- Модели
- Справочник по API