Django能自动创build一个相关的一对一模型吗?

我在不同的应用程序中有两个模型:modelA和modelB。 他们有一对一的关系。 有没有办法django可以自动创build和保存ModelA时保存ModelB?

class ModelA(models.Model): name = models.CharField(max_length=30) class ModelB(models.Model): thing = models.OneToOneField(ModelA, primary_key=True) num_widgets = IntegerField(default=0) 

当我保存一个新的ModelA时,我想要一个条目在ModelB中自动保存。 我怎样才能做到这一点? 有没有在ModelA中指定的方法? 或者这是不可能的,我只需要在视图中创build和保存ModelB?

编辑说模型是在不同的应用程序。

看看在Django讨厌 AutoOneToOneField。 从文档:

 from annoying.fields import AutoOneToOneField class MyProfile(models.Model): user = AutoOneToOneField(User, primary_key=True) home_page = models.URLField(max_length=255) icq = models.CharField(max_length=255) 

(Django的烦人是一个伟大的小图书馆,包括像render_to装饰和get_object_or_none和get_config函数的gem)

像m000指出,你的模型存在于不同的应用程序。 通常情况下,您使用的是未编写的应用程序,因此为了实现更新,您需要采用分离的方式来创build逻辑相关的模型。 我认为这是首选解决scheme,我们将其用于非常大的项目中。

通过使用信号:

在您的models.py中:

 from django.db.models import signals def create_model_b(sender, instance, created, **kwargs): """Create ModelB for every new ModelA.""" if created: ModelB.objects.create(thing=instance) signals.post_save.connect(create_model_b, sender=ModelA, weak=False, dispatch_uid='models.create_model_b') 

如果两个应用程序都是现成的,您可以创build一个单独的应用程序来保存这个models.py文件。

最直接的方法是覆盖 ModelA 的保存方法 :

 class ModelA(models.Model): name = models.CharField(max_length=30) def save(self, force_insert=False, force_update=False): is_new = self.id is None super(ModelA, self).save(force_insert, force_update) if is_new: ModelB.objects.create(thing=self) 

我想你想使用Django的模型inheritance 。 如果您满足以下条件,那么这非常有用:ModelA是ModelB(例如,Restaurant是位置)。

你可以定义:

  class ModelB(models.Model):
     field1 = models.CharField(...) 

类ModelA(ModelB):
field2 = models.CharField(…)

现在可以创buildModelA的实例并设置field2 field1。 如果这个模型被保存,它也会创build一个ModelB的实例,它获得了field1的赋值。 这一切都是在幕后透明地完成的。

虽然你可以做到以下几点:

  a1 = ModelA()
 a1.field1 =“foo”
 a1.field2 =“酒吧”
 a1.save()
 a2 = ModelA.objects.get(id = a1.id)
 a2.field1 ==“foo”#为真
 a2.field2 ==“bar”#为真
 b1 = ModelB.objects.get(id = a1.id)
 b1.field1 ==“foo”#为真
 #b1.field2没有定义 

我知道这有点晚,但我想出了一个更清洁,更优雅的解决scheme。 考虑这个代码:

 class ModelA(models.Model): name = models.CharField(max_length=30) @classmethod def get_new(cls): return cls.objects.create().id class ModelB(models.Model): thing = models.OneToOneField(ModelA, primary_key=True, default=ModelA.get_new) num_widgets = IntegerField(default=0) 

当然你也可以使用lambda,只要你返回相关对象的整数ID 🙂

您可以使用保存logging后触发的post_save-hook 。 有关django信号的更多文档,请参阅此处 。 在这个页面上 ,你可以find一个关于如何在模型上应用钩子的例子。

只需要创build一个函数来创build并返回一个空的ModelA,并将“thing”的默认命名参数设置为该函数。