在迁移中处理 GenericRelation 和 GenricForeignKey

Posted

技术标签:

【中文标题】在迁移中处理 GenericRelation 和 GenricForeignKey【英文标题】:Dealing GenericRelation and GenricForeignKey inside migrations 【发布时间】:2020-07-24 17:07:42 【问题描述】:

我有带有 GenricForeigKey 和 GenericRelation 字段的模型。

class Datasheet(models.Model):
    package1 = GenericRelation('PackageInstance')
    ...

class PackageInstance(models.Model):
    content_object = GenericForeignKey()
    object_id = models.PositiveIntegerField(null=True)
    content_type = models.ForeignKey(ContentType, null=True, on_delete=models.CASCADE)
    ....

我正在从另一个模型迁移,在我的迁移中我想创建新实例。

    for ds in Datasheet.objects.all():
        pi = PackageInstance.objects.create(content_object=ds)

然而这失败了

TypeError: DesignInstance() got an unexpected keyword argument 'content_object'

另外,ds.package1.all() 也会失败。

AttributeError: 'Datasheet' object has no attribute 'package1'

我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

我做了一些研究,但没有找到我问题的直接答案。 要记住的最重要的事情是模型方法在迁移中不可用。这包括由内容类型框架创建的字段。但是,object_idcontent_type 将在那里。

我的解决方案是简单地手工制作。

ContentType = apps.get_model('contenttypes', 'ContentType')

Datasheet = apps.get_model('api', 'Datasheet')
DatasheetContentType = ContentType.objects.get(model=Datasheet._meta.model_name, app_label=Datasheet._meta.app_label)

for ds in Datasheet.objects.all():
    di = DesignInstance.objects.create(object_id=ds.id, content_type=DatasheetContentType)

【讨论】:

我建议改用ContentType.objects.get_for_model(Datasheet),因为它会自动创建缺少的内容类型并清除缓存。

以上是关于在迁移中处理 GenericRelation 和 GenricForeignKey的主要内容,如果未能解决你的问题,请参考以下文章

GenericRelation 的 Django m2m_changed 信号,有可能吗?

django prefetch_related 是不是应该与 GenericRelation 一起使用

有没有办法让石墨烯与 django GenericRelation 字段一起工作?

在 Django 中处理生产迁移和开发迁移

Django中app的model相互引用问题

Django ReverseSingleRelatedObjectDescriptor.__set__ ValueError