我将django从1.8.4升级到1.11.6并遇到问题。我有两个模型:
class File(models.Model):
title = models.CharField(max_length=128, verbose_name=_('title'))
description = models.CharField(
max_length=255, blank=True, null=True, verbose_name=_('description')
)
class Task(models.Model):
output_data = models.ManyToManyField(
File, blank=True, verbose_name=_('output_data')
)
我正在运行manage.py loaddata,其中包含以上模型的以下数据:
files.json:
[ { "fields": { "description": "", "title": "Data file 2", }, "model": "files.file", "pk": 2 } ]
tasks.json:
[ { "fields": { "output_data": [2] }, "model": "tasks.task", "pk": 1 } ]
loaddata创建文件和任务,但不创建m2m关系。在更新之前一切正常。
UPD:我发现loaddata创建了m2m关系:local / lib / python2.7 / site-packages / django / db / models / fields / related_descriptors.py:972,方法集:
def set(self, objs, **kwargs):
if not rel.through._meta.auto_created:
opts = self.through._meta
raise AttributeError(
"Cannot set values on a ManyToManyField which specifies an "
"intermediary model. Use %s.%s's Manager instead." %
(opts.app_label, opts.object_name)
)
# Force evaluation of `objs` in case it's a queryset whose value
# could be affected by `manager.clear()`. Refs #19816.
objs = tuple(objs)
clear = kwargs.pop('clear', False)
db = router.db_for_write(self.through, instance=self.instance)
with transaction.atomic(using=db, savepoint=False):
if clear:
self.clear()
self.add(*objs)
else:
old_ids = set(self.using(db).values_list(self.target_field.target_field.attname, flat=True))
new_objs = []
for obj in objs:
fk_val = (
self.target_field.get_foreign_related_value(obj)[0]
if isinstance(obj, self.model) else obj
)
if fk_val in old_ids:
old_ids.remove(fk_val)
else:
new_objs.append(obj)
self.remove(*old_ids)
self.add(*new_objs)
我理解这里发生了什么,但我没有看到正在发生的事情的逻辑。如果有人知道为什么会这样,请向我解释。 感谢