Справочник по связям между объектами¶
-
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)¶
-
aadd
(*objs, bulk=True, through_defaults=None)¶ Асинхронная версия:
aadd
Добавляет указанные объекты модели в набор связанных объектов.
Пример:
>>> 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 4.2:Добавлен метод
aadd()
.
-
create
(through_defaults=None, **kwargs)¶
-
acreate
(through_defaults=None, **kwargs)¶ Асинхронная версия:
acreate
Создает новый объект, сохраняет его и помещает в набор связанных объектов. Возвращает только что созданный объект:
>>> 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
.
-
remove
(*objs, bulk=True)¶
-
aremove
(*objs, bulk=True)¶ Асинхронная версия:
aremove
Удаляет указанные объекты модели из набора связанных объектов:
>>> 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
не существует.Changed in Django 4.2:Добавлен метод
aremove()
.
-
clear
(bulk=True)¶
-
aclear
(bulk=True)¶ Асинхронная версия:
aclear
Удаляет все объекты из набора связанных объектов:
>>> b = Blog.objects.get(id=1) >>> b.entry_set.clear()
Обратите внимание, что это не удаляет связанные объекты, а просто разъединяет их.
Как и
remove()
,clear()
доступен только вForeignKey
, гдеnull = True
, а также принимает ключевой аргументbulk
.Для отношений многие-ко-многим ключевой аргумент
bulk
не существует.Changed in Django 4.2:Добавлен метод
aclear()
.
-
set
(objs, bulk=True, clear=False, through_defaults=None)¶
-
aset
(objs, bulk=True, clear=False, through_defaults=None)¶ Асинхронная версия:
aset
Замените набор связанных объектов:
>>> 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 4.2:Добавлен метод
aset()
.
Примечание
Отметим, что
add()
,aadd()
,create()
,acreate()
,remove()
,aremove()
,clear()
,aclear()
,set()
иaset()
- все они применяют изменения базы данных немедленно для всех типов связанных полей. Другими словами, нет необходимости вызыватьsave()
/asave()
на обоих концах связи.При использовании
prefetch_related()
методыadd()
,aadd()
,remove()
,aremove()
,clear()
,aclear()
,set()
иaset()
очищают префетишированный кэш.
Django 5.0
Содержание
Дополнительно
Вы здесь:
-
Документация Django Django 5.0
- Справочник по API
- Модели
- Справочник по связям между объектами
- Модели
- Справочник по API