Django loaddata不会创建m2m关系

时间:2017-11-03 19:20:35

标签: python json django fixtures loaddata

我将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)

我理解这里发生了什么,但我没有看到正在发生的事情的逻辑。如果有人知道为什么会这样,请向我解释。 感谢

0 个答案:

没有答案