Consider the following code, in which I have one parent, and all the child models related to the parent by ForeignKey
relationship. Each child may have their own child, making the whole family look like a tree structure.
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')
Upon making an object for Parent
, I want to create all the child objects.
I guess I can create all the child objects like this:
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)
...
But you know, this doesn't look very good. Is there any built-in Django method that handles this kind of parent-child object creation in chain?
Override save()
method of model as,
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')
In Django, you would usually use Signals for this. A standard situation is when you create a new User
and want their Profile
to be automatically created.
Example from 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)
So in your case, you can use post_save
to connect the Parent
with a function that creates all the child items.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With