首页 > 解决方案 > Django外键:更新记录有键值时自动查找相关对象

问题描述

我有在架构中没有定义外键的遗留代码。该行的原始数据自然包括父项的键值。我对 postgresql 的第一次移植尝试只是用原始值更新了该字段:我没有将外键添加到 Django 的模型中。

现在我正在尝试添加外键以使架构更具信息性。

当我添加外键时,django 的更新要求我提供父对象的一个​​实例:我不能再通过简单地提供键值来更新。但这很麻烦,因为现在我需要在我的代码中包含所有关系的知识来获取相关对象,并且每个模型都有特定的更新调用。这对我来说似乎很疯狂,至少从我现在的位置开始,所以我觉得我真的错过了一些东西。

目前,更新代码只是在幸福的无知中推送行。更新代码对于表是通用的,当没有关系时这很容易。

Django 的模型数据意味着我可以为任何给定的模型动态地找到相关对象,这样做意味着我仍然可以保持非常抽象的表更新逻辑。所以这就是我想做的事情。或者只是进行原始 SQL 更新。

即使我找不到解决方案,是否已经存在?我期待着尴尬。

ValueError 来自 django ORM 代码,它确切地知道它期望哪个模型以及相关字段是什么:如果要查找相关对象的实例,则缺少步骤。

db.models.fields.related_descriptors.py:在这个抛出异常的代码中,值应该是父模型的一个实例。相反,价值是关键价值。这基本上告诉我如何检查模型以提前处理这个问题,但我想知道我是否在重新发明轮子。

 if value is not None and not isinstance(value, self.field.remote_field.model._meta.concrete_model):
            raise ValueError(
                'Cannot assign "%r": "%s.%s" must be a "%s" instance.' % (
                    value,
                    instance._meta.object_name,
                    self.field.name,
                    self.field.remote_field.model._meta.object_name,
                )
            )

标签: djangodjango-orm

解决方案


您可以使用 _id 后缀直接设置 id 值

对于给定的模型

class Album(models.Model):
    artist = models.ForeignKey(Musician, on_delete=models.CASCADE)

您可以通过以下方式通过 id 设置艺术家

Album.objects.create(artist_id=2)

推荐阅读