2012-02-19 101 views

回答

2

当您创建ManyToManyField而未指定中间表时(使用through)Django会为您生成一个表。这个表格只需要两个模型的pks,所以不需要从其他对象中选择任何东西来保存新的关联关系。

将为它们中的每一个创建一个新行,可能使用许多插入,但不一定需要很多数据库调用(例如,可能有多个插入命令的单个SQL查询)。这些创建(对象的pks)所需的所有信息都可用,因此不需要任何更多的数据库命中。

更新:似乎我错了。纵观源(Django的/ DB /模型/场/ related.py),我看到它执行对每个对象的独立创作:在做之前是

for obj_id in new_ids: 
    self.through._default_manager.using(db).create(**{ 
     '%s_id' % source_field_name: self._pk_val, 
     '%s_id' % target_field_name: obj_id, 
    }) 

,它还会检查是否有任何PKS供应在数据库中已经存在(为了避免重复的条目/唯一约束违规):使用

vals = self.through._default_manager.using(db).values_list(target_field_name, flat=True) 
vals = vals.filter(**{ 
    source_field_name: self._pk_val, 
    '%s__in' % target_field_name: new_ids, 
}) 
new_ids = new_ids - set(vals) 

该检查虽然有一个查询做...

0

你有没有试过检查自己QuerySet.query属性?

+3

'add'和'remove'没有查询属性来检查,但也有类似的方法。执行'from django.db import connection',然后在添加或删除多对多关系之前和之后打印'connection.queries'。 – Alasdair 2012-02-19 16:12:55

+0

谢谢,不知道。 – side2k 2012-02-20 04:03:31