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
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
Both sides of a
class Topping(models.Model): # ... pass class Pizza(models.Model): toppings = models.ManyToManyField(Topping)
In this example, the methods below will be available both on
Adds the specified model objects to the related object set.
>>> b = Blog.objects.get(id=1) >>> e = Entry.objects.get(id=234) >>> b.entry_set.add(e) # Associates Entry e with Blog b.
You can use the
bulk=Falseargument to instead have the related
manager perform the update by calling
add()with a many-to-many relationship, however, will not
bulkargument 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_changedsignal, which will
add()on a relation that already exists won’t duplicate the
relation, but it will still trigger signals.
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
create(). Django figures out that the new
blogfield should be set to
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.
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
means no model
save()methods are called; listen to the
m2m_changedsignal if you wish to
execute custom code when a relationship is deleted.
ForeignKeyobjects, this method only
null=True. If the related field can’t be set to
NULL), then an object can’t be removed from a relation without
being added to another. In the above example, removing
b.entry_set()is equivalent to doing
e.blog = None, and because
null=True, this is invalid.
ForeignKeyobjects, this method accepts
bulkargument to control how to perform the operation.
save()method of each individual model
instance is called instead. This triggers the
post_savesignals and comes at the
expense of performance.
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
clear()is only available on
null=Trueand it also
Replace the set of related objects:
>>> new_list = [obj1, obj2, obj3] >>> e.related_set.set(new_list)
This method accepts a
clearargument to control how to perform the
False(the default), the elements missing from the
new set are removed using
remove()and only the new ones are added.
clear()method is called instead and the
whole set is added at once.
bulkargument is passed on to
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
set()all apply database changes immediately for all types of
related fields. In other words, there is no need to call
on either end of the relationship.
Also, if you are using an intermediate model for a many-to-many relationship, then the
If you use
the prefetched cache.Changed in Django 1.11:
The clearing of the prefetched cache described above was added.