【问题标题】:Django - Create all foreign key objects upon creating a parent objectDjango - 在创建父对象时创建所有外键对象
【发布时间】:2019-01-17 18:08:53
【问题描述】:

考虑下面的代码,其中我有一个父模型,所有子模型都通过ForeignKey 关系与父模型相关。每个孩子都可能有自己的孩子,使整个家庭看起来像一个树状结构。

class Parent(models.Model):
    field = models.CharField(max_length=100, primary_key=True)

class Child_1(models.Model):
    parent = models.ForeignKey(Parent, models.CASCADE, related_name='aa')

class Child_2(models.Model):
    parent = models.ForeignKey(Parent, models.CASCADE, related_name='aa')

class Child_1_Child_1(models.Model):
    parent = models.ForeignKey(Child_1, models.CASCADE, related_name='aa')

class Child_1_Child_2(models.Model):
    parent = models.ForeignKey(Child_1, models.CASCADE, related_name='aa')

在为Parent 创建对象后,我想创建所有子对象。

我想我可以像这样创建所有子对象:

parent = Parent.objects.create(**kwargs)
child_1 = Child_1.objects.create(parent=parent)
child_2 = Child_2.objects.create(parent=parent)
child_1_child_1 = Child_1_Child_1.objects.create(parent=child_1)
child_1_child_2 = Child_1_Child_2.objects.create(parent=child_1)
...

但是你知道,这看起来不太好。有没有内置的 Django 方法来处理这种链式父子对象的创建?

【问题讨论】:

  • 好吧,我个人想知道你为什么要首先构造所有这些对象。如果某些模型需要额外的列(没有默认值),那该怎么办?
  • @WillemVanOnsem 这用于数据管理系统。当用户单击父对象时,它将重定向到用户可以编辑该父对象的所有子字段的页面。最初所有子字段都是空白的,如果空白,用户可以填写字段,否则,用户可以更新字段值。但要做到这一点,子对象需要存在于数据库中,以便用户可以编辑这些子字段

标签: django django-models


【解决方案1】:

在 Django 中,您通常会为此使用 Signals。标准情况是当您创建一个新的 User 并希望自动创建其 Profile

来自this answer的示例:

def create_profile(sender, **kwargs):
    user = kwargs["instance"]
    if kwargs["created"]:
        up = UserProfile(user=user, stuff=1, thing=2)
        up.save()

post_save.connect(create_profile, sender=User)

因此,在您的情况下,您可以使用 post_saveParent 与创建所有子项的函数连接起来。

【讨论】:

    【解决方案2】:

    我建议使用django-mptt 之类的东西来处理 Django 中的树。

    如果您真的想继续手动操作,请参阅@C14L 答案。或者只是将您的代码放入 Parent 方法中,然后调用类似 parent.create_children() 的方法。

    【讨论】:

      【解决方案3】:

      覆盖模型的save()方法为,

      class Parent(models.Model):
          field = models.CharField(max_length=100, primary_key=True)
      
          def save(self, *args, **kwargs):
              is_new = not self.pk
              super().save(*args, **kwargs)
              if is_new:
                  Child_1.objects.create(parent=self)
                  Child_2.objects.create(parent=self)
      
      
      class Child_1(models.Model):
          parent = models.ForeignKey(Parent, models.CASCADE, related_name='aa')
      
          def save(self, *args, **kwargs):
              is_new = not self.pk
              super().save(*args, **kwargs)
              if is_new:
                  Child_1_Child_1.objects.create(parent=self)
      
      
      class Child_2(models.Model):
          parent = models.ForeignKey(Parent, models.CASCADE, related_name='aa')
      
          def save(self, *args, **kwargs):
              is_new = not self.pk
              super().save(*args, **kwargs)
              if is_new:
                  Child_1_Child_2.objects.create(parent=self)
      
      
      class Child_1_Child_1(models.Model):
          parent = models.ForeignKey(Child_1, models.CASCADE, related_name='aa')
      
      
      class Child_1_Child_2(models.Model):
          parent = models.ForeignKey(Child_1, models.CASCADE, related_name='aa')

      【讨论】:

        猜你喜欢
        • 2019-07-28
        • 2011-05-10
        • 2020-10-12
        • 2014-04-04
        • 1970-01-01
        • 2021-10-30
        • 2023-01-02
        • 2020-01-30
        • 1970-01-01
        相关资源
        最近更新 更多