关系对象参考Link to this heading
“关系管理器”是一个用于处理“一对多”和“多对多”关联关系的管理器。在以下两种情况用到:
“另一边”的关联关系
ForeignKey。即: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中可用。双边关系
ManyToManyFieldclass Topping(models.Model): # ... pass class Pizza(models.Model): toppings = models.ManyToManyField(Topping)在这个例子中,下文列出的方法在
topping.pizza_set和pizza.toppings中均可用。
将特定的模型对象加入关联对象集合。
举例:
>>> 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()来执行更新操作。Using
add()with a many-to-many relationship, however, will not call anysave()methods (thebulkargument doesn't exist), but rather create the relationships usingQuerySet.bulk_create(). If you need to execute some custom logic when a relationship is created, listen to them2m_changedsignal, which will triggerpre_addandpost_addactions.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*objsargument.Use the
through_defaultsargument to specify values for the new intermediate model instance(s), if needed.
创建一个新对象,保存至数据库,并将其放入关联对象集合内。返回刚创建的对象:
>>> 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.等同于(但更简单):
>>> 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)无需指定定义了模型间关系的关键字参数。在上述例子中,我们并未向
create()传递参数blog。Django 知道要将新Entry对象的blog字段设置为b。Use the
through_defaultsargument to specify values for the new intermediate model instance, if needed.
从关系集合中移除特定的对象:
>>> 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. Usingremove()with a many-to-many relationship, however, will delete the relationships usingQuerySet.delete()which means no modelsave()methods are called; listen to them2m_changedsignal 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*objsargument.For
ForeignKeyobjects, this method only exists ifnull=True. If the related field can't be set toNone(NULL), then an object can't be removed from a relation without being added to another. In the above example, removingefromb.entry_set()is equivalent to doinge.blog = None, and because theblogForeignKeydoesn't havenull=True, this is invalid.For
ForeignKeyobjects, this method accepts abulkargument to control how to perform the operation. IfTrue(the default),QuerySet.update()is used. Ifbulk=False, thesave()method of each individual model instance is called instead. This triggers thepre_saveandpost_savesignals and comes at the expense of performance.For many-to-many relationships, the
bulkkeyword argument doesn't exist.
清空关系集合:
>>> 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 onForeignKeys wherenull=Trueand it also accepts thebulkkeyword argument.For many-to-many relationships, the
bulkkeyword argument doesn't exist.
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 operation. IfFalse(the default), the elements missing from the new set are removed usingremove()and only the new ones are added. Ifclear=True, theclear()method is called instead and the whole set is added at once.For
ForeignKeyobjects, thebulkargument is passed on toadd()andremove().For many-to-many relationships, the
bulkkeyword 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 toclear()and the call toadd().For many-to-many relationships
set()accepts a list of either model instances or field values, normally primary keys, as theobjsargument.Use the
through_defaultsargument to specify values for the new intermediate model instance(s), if needed.