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.
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() отключены.
Если вы используете prefetch_related(), методы add(), remove(), clear(), и set() очищают кэш предварительной выборки.
Изменено в Django 1.11:
Было добавлено очищение кэша предварительной выборки, описанного выше.
Прямое присваивание
Набор связанных объектов можно заменить оптом одной операцией, присвоив ему новый итерируемый набор объектов:
Если отношение «один-ко-многим» имеет null=True, то связанный менеджер сначала разъединит любые существующие объекты в связанном наборе, прежде чем добавить содержимое new_list. В противном случае объекты в new_list будут добавлены к существующему связанному набору объектов.
Устарело начиная с версии 1.10: Прямое присваивание устарело в пользу метода set():
>>> e.related_set.set([obj1, obj2, obj3])
Это предотвращает путаницу в отношении присваивания, приводящего к неявной сохранению.