Spec-Zone.ru › Django 2.2

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

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

Изменено в Django 2.2:

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

Изменено в Django 2.2:

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

Изменено в Django 2.2:

Добавлен аргумент 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/2.2/ref/models/relations/

Spec-Zone.ru

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