我有一个具有以下模型的现有应用程序

class Contact(models.Model):
     lastname = models.CharField(max_length=200)
     firstname = models.CharField(max_length=200)
     ...

class Journalist(Contact):
     pass


我的数据库中有一个Contact,我希望它成为一个Journalist

在原始sql中,它似乎和insert into app_journalist values (25624);一样简单。在此的示例25624是现有联系人的ID。看来工作正常,django应用似乎很高兴。

但是,我想对django ORM做同样的事情。我已经尝试过多种方法,例如强制使用记者ID(Journalist(id=25624)),但它创建了一个新联系人,而不是链接到现有联系人。

Django ORM是否可以做到这一点?怎么样?

在此先感谢您的帮助

最佳答案

解决此问题的一种方法是(不更改模型结构)将contact_ptr实例的Journalist属性设置为适当的Contact实例。例如

contact = Contact.objects.get(pk = 25624)
journalist = Journalist(contact_ptr = contact)
journalist.save()


如果您首先查看表app_journalist,这将变得更容易理解。它只有一列contact_ptr_id。因此,当您执行insert into app_journalist values (25624)时,您将在SQL级别上设置contact_ptr_id = 25624。相应地,应将contact_ptr = <instance of Contact>设置为ORM级别。

更新资料

还有其他方法可以解决该问题,但是它们将需要更改现有模型。作为@ bugspy.net pointed out,您可以使用一般关系。或者,您可以声明一个附加的type字段,以指定该联系人是记者还是同事等。

更新2

还请看一下该demo snippet(和complete code),它使您可以使用多态继承(SQLAlchemy已经做到了)。

更新3

正如@luc自己指出的(请参阅下面的评论)

journalist = Journalist(contact_ptr = contact)


单靠一个人还不够。这会将firstnamelastnamecontact覆盖为""。为避免这种情况,您必须将每个字段明确分配给。

10-08 03:36