Spec-Zone.ru › Django 4.2

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

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

Изменено в 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 определяет, что поле Entry, нового объекта blog, должно быть установлено в b.

Используйте аргумент through_defaults, чтобы указать значения для нового экземпляра вспомогательной модели, если необходимо. Вы можете использовать вызываемые объекты в словаре through_defaults.

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

acreate() метод был добавлен.

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 отсутствует.

Изменено в 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 отсутствует.

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

Изменено в 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 Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/4.2/ref/models/relations/

Spec-Zone.ru

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