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.
class Topping(models.Model):
# ...
pass
class Pizza(models.Model):
toppings = models.ManyToManyField(Topping)
В этом примере методы ниже будут доступны как в topping.pizza_set, так и в pizza.toppings.
add(*objs, bulk=True)
Добавляет указанные объекты модели в набор связанных объектов.
Пример:
>>> 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.
Изменено в Django 1.9:
Добавлен параметр bulk. В более старых версиях обновления внешних ключей всегда выполнялись с помощью save(). Используйте bulk=False, если вам требуется старое поведение.
create(**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.
Обратите внимание, что нет необходимости указывать ключевой аргумент модели, определяющей отношение. В приведенном выше примере мы не передаём параметр blog в create(). Django определяет, что поле Entry нового объекта blog должно быть установлено в b.
remove(*objs)
Удаляет указанные объекты модели из набора связанных объектов:
>>> 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, и поскольку blogForeignKey не имеет null=True, это недействительно.
Для объектов ForeignKey, этот метод принимает аргумент bulk для управления способом выполнения операции. Если True (по умолчанию), используется QuerySet.update(). Если bulk=False, вместо этого вызывается метод save() каждого отдельного экземпляра модели. Это активирует сигналы pre_save и post_save и влечёт за собой потери производительности.
clear()
Удаляет все объекты из набора связанных объектов:
>>> b = Blog.objects.get(id=1)
>>> b.entry_set.clear()
Обратите внимание, что это не удаляет связанные объекты — оно просто отвязывает их.
Точно так же, как remove(), clear() доступно только для ForeignKey, где null=True, и оно также принимает ключевой аргумент bulk.
Этот метод принимает аргумент clear для управления способом выполнения операции. Если False (по умолчанию), отсутствующие элементы из нового набора удаляются с помощью remove(), и только новые добавляются. Если clear=True, вместо этого вызывается метод clear(), и весь набор добавляется сразу.
Обратите внимание, что поскольку set() представляет собой составную операцию, она подвержена гонкам. Например, новые объекты могут быть добавлены в базу данных между вызовом clear() и вызовом add().
Примечание
Обратите внимание, что add(), create(), remove(), clear(), и set() немедленно применяют изменения в базе данных для всех типов связанных полей. Другими словами, нет необходимости вызывать save() на обоих концах отношения.
Также, если вы используете промежуточную модель для связи «многие ко многим», то методы add(), create(), remove(), и set() отключены.
Прямая присваиваемость
Набор связанных объектов может быть заменён оптом одной операцией путём присваивания нового итерируемого объекта ему:
Если отношение «один ко многим» имеет null=True, то связанный менеджер сначала отвяжет все существующие объекты в связанном наборе, прежде чем добавить содержимое new_list. В противном случае объекты в new_list будут добавлены к существующему набору связанных объектов.
Изменено в Django 1.9:
В более ранних версиях прямая присваиваемость выполняла clear() в сочетании с add(). Теперь она выполняет set() с ключевым аргументом clear=False.
Устарело начиная с версии 1.10: Прямая присваиваемость устарела в пользу метода set():
>>> e.related_set.set([obj1, obj2, obj3])
Это предотвращает путаницу при присваивании, которое приводит к неявной сохранению.