“Менеджер связанных объектов” – это менеджер, который используется для связей один-ко-многим и многие-ко-многим. Это происходит в двух случаях:
“Обратная связь” для 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.
Добавляет указанный объект модели к множеству связанных объектов.
Например:
>>> 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(), а создает связывающие объекты с помощью QuerySet.bulk_create(). Если вам необходима дополнительная логика при обновлении связей, обрабатывайте сигнал m2m_changed.
Был добавлен аргумент bulk. В предыдущих версих обновления внешнего ключа всегда выполнялось с помощью save(). Используйте bulk=False для предыдущего поведения.
Создает новый объект, сохраняет его и добавляет к связанным объектам. Возвращает созданный объект:
>>> 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.
Удаляет указанный объект из списка связанных объектов:
>>> 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.
Метод существует только для ForeignKey с null=True. Если внешний ключ не может быть установлен в None (NULL), объект не может быть удален из связи без добавления нового объекта. В примере выше, удаление e из b.entry_set() аналогично e.blog = None, и так как ForeignKey в blog не содержит null=True, это невозможно.
Для объектов ForeignKey метод принимает аргумент bulk, который определяет работу сохранения. Если указать True (по умолчанию), будет использоваться QuerySet.update(). При bulk=False будет вызван метод save() для каждого объекта. Это вызывает сигналы pre_save и post_save, что работает немного медленне.
Удаляет все объекты из списка связанных:
>>> b = Blog.objects.get(id=1)
>>> b.entry_set.clear()
Заметим, что связанные объекты не удаляются – просто разрывается связь.
Так же как и remove(), clear() доступен только для ForeignKey с null=True и принимает аргумент bulk.
Удаляет все объекты из списка связанных:
>>> new_list = [obj1, obj2, obj3]
>>> e.related_set.set(new_list)
Этот метод принимает аргумент clear, чтобы управлять выполнение операции. При False (по умолчанию), объекты, которые отсутствуют в новом множестве, будут удалены с помощью команды remove(), и только новые объекты будут добавлены. При clear=True, вызывается метод clear() и все множество добавляет за раз.
Аргумент bulk передается в add().
Обратите внимание, т.к. set() составная операция, она подвержена состоянию гонки. Например, в базу данных могут быть добавлены новые объекты между вызовами clear() и add().
Примечание
Обратите внимание, add(), create(), remove() и clear() сразу сохраняют изменения для всех типов связей. Другими словами, нет необходимости вызывать save().
Также, если вы используете промежуточную модель для связи многое ко многим, некоторые методы могут быть не доступны.
Список связанных объектов можно поменять одной операцией, назначив список объектов:
>>> new_list = [obj1, obj2, obj3]
>>> e.related_set = new_list
Если внешний ключ определен с null=True, сначала будут удалены все связанные объекты перед добавлением объектов из new_list. Иначе объекты из new_list будут добавлены к списку существующих объектов.
В предыдущих версиях при прямом присваивании вызывался метод clear() и затем add(). Теперь используется метод set() с аргументом clear=False.
Введите слова для поиска или имя модуля, класса или функции.
Mar 31, 2016