Spec-Zone.ru › Django 6.0

Справочник связанных объектов

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 можно использовать вызываемые объекты в качестве значений: они будут вызваны один раз перед созданием любых экземпляров промежуточной модели.

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 этот метод принимает аргумент bulk, определяющий способ выполнения операции. Если задано True (по умолчанию), используется QuerySet.update(). Если задано bulk=False, вместо этого вызывается метод save() каждого отдельного экземпляра модели. Это вызывает сигналы pre_save и post_save и снижает производительность.

Для связей «многие-ко-многим» именованный аргумент bulk не существует.

clear(bulk=True)
aclear(bulk=True)

Асинхронная версия: aclear

Удаляет все объекты из набора связанных объектов:

>>> 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)
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 можно использовать вызываемые объекты в качестве значений: они будут вызваны один раз перед созданием любых экземпляров промежуточной модели.

Примечание

Обратите внимание: add(), aadd(), create(), acreate(), remove(), aremove(), clear(), aclear(), set() и aset() немедленно применяют изменения в базе данных для всех типов связанных полей. Иными словами, вызывать save()/asave() на любой стороне отношения не нужно.

Если вы используете prefetch_related(), методы add(), aadd(), remove(), aremove(), clear(), aclear(), set() и aset() очищают предварительно загруженный кэш.

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/6.0/ref/models/relations/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API