Django模型 - 外键作为主键
Django模型 - 外键作为主键
我有以下两个表
在models.py中
class Foo(models.Model): uuid = models.CharField(_('UUID'), primary_key=True, default=uuid4)
以及
class FooExt(models.Model): uuid = models.ForeignKey(Foo, verbose_name=_('UUID'), primary_key=True) time = models.DateTimeField(_('Create DateTime'), auto_now_add=True)
基本上,我有Foo
和FooExt
。我想要FooExt
之间的一对一关系。这就是为什么我将FooExt
的主键设置为指向Foo
的外键(不确定这样做是否正确)。
现在我向Foo
添加一个条目。是否会自动创建FooExt
的条目?还是我需要手动添加Foo
和FooExt
的条目?
有什么方法可以获得“自动”添加功能吗?从概念上讲,这两个表描述了相同的内容,但我只是不想在Foo
中添加额外的信息。所以如果在Foo
中添加一个条目会自动创建相应的FooExt
,那就太好了。
Django模型 - 外键作为主键的问题常常出现在需要将外键字段作为主键的情况下。这种情况下,Django默认会为每个模型创建一个自增的主键字段。然而,有时我们希望将外键作为主键,这就需要采取一些额外的步骤来实现。
在处理这个问题时,可以参考django-annoying库中的AutoOneToOneField。这个库提供了一个AutoOneToOneField字段,它继承自OneToOneField,并且在创建一个新的实例时,自动为外键字段创建一个相关的一对一关系模型。这个库的源代码可以在以下链接中找到:https://github.com/skorokithakis/django-annoying
另外,在Stack Overflow上也有关于这个问题的回答:Can Django automatically create a related one-to-one model?。这个回答中提到了一种解决方法,即通过覆盖模型的save方法,在保存模型实例之前创建相关的一对一关系模型。
总结起来,解决Django模型中外键作为主键的问题可以通过使用django-annoying库中的AutoOneToOneField字段或者通过覆盖模型的save方法来实现。
问题:Django模型中的外键作为主键的原因和解决方法
在上述内容中,有人提出了一个关于Django模型中外键作为主键的问题,并提供了解决方法。下面将对问题的原因和解决方法进行整理。
原因:
在Django的模型中,有时候我们希望将一个外键字段作为主键。这种情况下,我们不需要为主键创建一个新的字段,而是直接使用外键字段作为主键。然而,默认情况下,Django并不支持将外键字段作为主键。因此,我们需要找到一种解决方法。
解决方法:
根据上述内容中的讨论,我们可以使用以下方法解决将外键字段作为主键的问题:
1. 在模型中定义外键字段和其他字段。
2. 重写模型的save方法,将父类的save方法调用放在最前面,以确保先保存父模型。
3. 创建一个新的相关模型对象,并将外键字段的值设置为父模型对象。
4. 保存相关模型对象。
以下是一个示例代码:
class Foo(models.Model): # 定义其他字段 .... def save(self, *args, **kwargs): # 调用父类的save方法 super(Foo, self).save(*args, **kwargs) # 创建相关模型对象 foo_ext = FooExt() # 设置外键字段的值为父模型对象 foo_ext.uuid = self # 保存相关模型对象 foo_ext.save()
需要注意的是,在保存相关模型对象之前,可以添加逻辑来检查相关模型对象是否已经存在。这样,如果有人创建了一个父模型对象,并且更新了它,第二次调用save()方法将不会覆盖已存在的相关模型对象。
参考链接:
http://stackoverflow.com/questions/907695
Django模型中的外键作为主键的问题产生的原因是在使用外键时,如果需要将其作为主键,需要在外键上添加unique=True。然而,使用外键的情况下,当创建一个主键实例时,并不会自动创建与之关联的外键实例。如果希望在创建主键实例时自动创建外键实例,可以在主键模型的save方法中重载保存方法,如下所示:
class Foo(models.Model): def save(self, *args, **kwargs): super(Foo, self).save(*args, **kwargs) foo_ext = FooExt() foo_ext.uuid = self foo_ext.save()
通过重载save方法,可以在保存主键实例时同时创建并保存外键实例。
然而,在第三点中,作者提到在重载save方法时会产生无限递归的问题,因为在save方法中又调用了self.save()。这是因为在重载save方法时,需要确保仅在创建主键实例时执行保存操作,而不是在每次保存时都执行。修正方法是将`foo_ext.uuid`改为`foo_ext`,即将外键实例赋值给主键实例的uuid字段。
为了在Django模型中使用外键作为主键,可以通过添加unique=True来确保主键的唯一性,并在主键模型的save方法中重载保存方法,实现在创建主键实例时自动创建并保存外键实例。