这里有一些数据库高尔夫。假设我有一个对象:
class A(models.Model):
b = models.ManyToManyField(B)
#Many other fields
现在假设我想对字段b进行批量更新。
some_objects = A.filter(q).values('id','b')
#Populate a map of ids
related_map = {
some_objects[0]['id']: [1,2],
some_objects[1]['id']: [1],
#etc.
}
现在我想要做的是这样的事情:
for (id,related_ids) in related_map.iteritems():
A.filter(id=id).update(b=related_ids)
引发了FieldError。当然,我可以这样做
for (id,related_ids) in related_map.iteritems():
a = A.objects.get(id=id)
a.b = related_ids
这有效,但似乎没必要。我已经从数据库中提取了我需要的所有数据,以便填充related_map。是否有内置的方法来更新多对多而无需查询数据库?
答案 0 :(得分:1)
除非您为关系声明中间模型,否则我认为ORM不会公开此内容。如果您不需要任何特殊行为(如触发信号),您应该能够使用直接SQL调用。类似的东西:
field = A._meta.get_field_by_name('b')[0]
tablename = field.m2m_db_table()
column_a_name = field.m2m_column_name()
column_b_name = field.m2m_reverse_name()
from django.db import connection, transaction
cursor = connection.cursor()
for (id, related_ids) in related_map.iteritems():
for related_id in related_ids:
cursor.execute("insert into %s (%s, %s) values (%s, %s)", (tablename, column_a_name, column_b_name, id, related_id))
transaction.commit_unless_managed()
https://docs.djangoproject.com/en/1.5/topics/db/sql/#executing-custom-sql-directly拥有关于交易控制选项的完整文档和讨论。
这些字段查找不是文档化API的一部分,因此在将来的版本中可能存在更改的风险。