Related objects reference¶
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
ForeignKeyrelation. That is:
from django.db import models class Reporter(models.Model): # ... pass class Article(models.Model): reporter = models.ForeignKey(Reporter)
In the above example, the methods below will be available on the manager
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
add(obj1[, obj2, ...])¶
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.
In the example above, in the case of a
e.save()is called by the related manager to perform the update. Using
add()with a many-to-many relationship, however, will not call any
save()methods, 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
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
create(). Django figures out that the new
blogfield should be set to
remove(obj1[, obj2, ...])¶
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
QuerySet.delete()which 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 exists if
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 the
null=True, this is invalid.Changed in Django 1.7.
ForeignKeyobjects, this method accepts a
bulkargument to control how to perform the operation. If
QuerySet.update()is used. If
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 them.
clear()is only available on
null=Trueand it also accepts the
clear()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.
Also, if you are using an intermediate model for a many-to-many relationship, some of the related manager’s methods are disabled.
A related object set can be replaced in bulk with one operation by assigning a new iterable of objects to it:
>>> new_list = [obj1, obj2, obj3] >>> e.related_set = new_list
If the foreign key relationship has
null=True, then the related manager
will first call
clear() to disassociate any existing objects in the related
set before adding the contents of
new_list. Otherwise the objects in
new_list will be added to the existing related object set.