class RelatedManager
A “related manager” is a manager used in a one-to-many or many-to-many related context. This happens in two cases:
The “other side” of a ForeignKey
relation. That is:
from django.db import models class Reporter(models.Model): # ... pass class Article(models.Model): reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
In the above example, the methods below will be available on the manager reporter.article_set
.
Both sides of a ManyToManyField
relation:
class Topping(models.Model): # ... pass class Pizza(models.Model): toppings = models.ManyToManyField(Topping)
In this example, the methods below will be available both on topping.pizza_set
and on pizza.toppings
.
add(*objs, bulk=True, through_defaults=None)
Adds the specified model objects to the related object set.
Example:
>>> b = Blog.objects.get(id=1) >>> e = Entry.objects.get(id=234) >>> b.entry_set.add(e) # Associates Entry e with Blog b.
In the example above, in the case of a ForeignKey
relationship, QuerySet.update()
is used to perform the update. This requires the objects to already be saved.
You can use the bulk=False
argument to instead have the related manager perform the update by calling e.save()
.
Using add()
with a many-to-many relationship, however, will not call any save()
methods (the bulk
argument doesn’t exist), but rather create the relationships using QuerySet.bulk_create()
. If you need to execute some custom logic when a relationship is created, listen to the m2m_changed
signal, which will trigger pre_add
and post_add
actions.
Using add()
on a relation that already exists won’t duplicate the relation, but it will still trigger signals.
For many-to-many relationships add()
accepts either model instances or field values, normally primary keys, as the *objs
argument.
Use the through_defaults
argument to specify values for the new intermediate model instance(s), if needed.
The through_defaults
argument was added.
create(through_defaults=None, **kwargs)
Creates a new object, saves it and puts it in the related object set. Returns the newly created object:
>>> 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.
This is equivalent to (but much simpler than):
>>> 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)
Note that there’s no need to specify the keyword argument of the model that defines the relationship. In the above example, we don’t pass the parameter blog
to create()
. Django figures out that the new Entry
object’s blog
field should be set to b
.
Use the through_defaults
argument to specify values for the new intermediate model instance, if needed.
The through_defaults
argument was added.
remove(*objs, bulk=True)
Removes the specified model objects from the related object set:
>>> b = Blog.objects.get(id=1) >>> e = Entry.objects.get(id=234) >>> b.entry_set.remove(e) # Disassociates Entry e from Blog b.
Similar to add()
, e.save()
is called in the example above to perform the update. Using remove()
with a many-to-many relationship, however, will delete the relationships using QuerySet.delete()
which means no model save()
methods are called; listen to the m2m_changed
signal if you wish to execute custom code when a relationship is deleted.
For many-to-many relationships remove()
accepts either model instances or field values, normally primary keys, as the *objs
argument.
For ForeignKey
objects, this method only exists if null=True
. If the related field can’t be set to None
(NULL
), then an object can’t be removed from a relation without being added to another. In the above example, removing e
from b.entry_set()
is equivalent to doing e.blog = None
, and because the blog
ForeignKey
doesn’t have null=True
, this is invalid.
For ForeignKey
objects, this method accepts a bulk
argument to control how to perform the operation. If True
(the default), QuerySet.update()
is used. If bulk=False
, the save()
method of each individual model instance is called instead. This triggers the pre_save
and post_save
signals and comes at the expense of performance.
For many-to-many relationships, the bulk
keyword argument doesn’t exist.
clear(bulk=True)
Removes all objects from the related object set:
>>> b = Blog.objects.get(id=1) >>> b.entry_set.clear()
Note this doesn’t delete the related objects – it just disassociates them.
Just like remove()
, clear()
is only available on ForeignKey
s where null=True
and it also accepts the bulk
keyword argument.
For many-to-many relationships, the bulk
keyword argument doesn’t exist.
set(objs, bulk=True, clear=False, through_defaults=None)
Replace the set of related objects:
>>> new_list = [obj1, obj2, obj3] >>> e.related_set.set(new_list)
This method accepts a clear
argument to control how to perform the operation. If False
(the default), the elements missing from the new set are removed using remove()
and only the new ones are added. If clear=True
, the clear()
method is called instead and the whole set is added at once.
For ForeignKey
objects, the bulk
argument is passed on to add()
and remove()
.
For many-to-many relationships, the bulk
keyword argument doesn’t exist.
Note that since set()
is a compound operation, it is subject to race conditions. For instance, new objects may be added to the database in between the call to clear()
and the call to add()
.
For many-to-many relationships set()
accepts a list of either model instances or field values, normally primary keys, as the objs
argument.
Use the through_defaults
argument to specify values for the new intermediate model instance(s), if needed.
The through_defaults
argument was added.
Note
Note that add()
, create()
, remove()
, clear()
, and set()
all apply database changes immediately for all types of related fields. In other words, there is no need to call save()
on either end of the relationship.
If you use prefetch_related()
, the add()
, remove()
, clear()
, and set()
methods clear the prefetched cache.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/2.2/ref/models/relations/