Spec-Zone.ru › Django 3.1

Ссылка на связанные объекты

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

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

Spec-Zone.ru

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