swozny13
swozny13

Reputation: 71

Create object when created another object in Django

Is it possible to create object when I created another object in Django?

I have code like this and I would like to create AnotherModel instance firstly and then Model instance (when creating AnotherModel).

class Model(models.Model):
    name = models.CharFiled(max_length=50)

class AnotherModel(models.Model):
    model = models.ForeignKey(Model, on_delete=models.CASCADE)
    description = models.TextField()

I tried use Django signals - pre_save.

@receiver(pre_save, sender=AnotherModel)
def save_model(sender, **kwargs):
    # some code

But I have exception like this:

ValueError: Cannot assign "u'Test": "AnotherModel.resource" must be a "Model" instance.

Upvotes: 5

Views: 4287

Answers (2)

lmiguelvargasf
lmiguelvargasf

Reputation: 69963

Yes, it is possible to create an object when another one is created. I think using a signal is possibly the best way to do it.

from django.db.models.signals import pre_save
from django.dispatch import receiver    

@receiver(pre_save, sender=AnotherModel)
def my_handler(sender, **kwargs):
    if sender.pk is None:
        sender.model = Model.objects.create(name="Name")

you just have to create an instance of AnotherModel so that the implemented signal is raised:

>>> o = AnotherModel.objects.create(description='This is a silly description')

You can check that an instance of Model has been created and assigned to o.model:

>>> o.model

Upvotes: 0

dani herrera
dani herrera

Reputation: 51715

Is it possible to create object when I created another object in Django?

Yes, you can, do you have two options:

1) Option 1: Overriding save ( Overriding predefined model methods )

from django.db import models

class AnotherModel(models.Model):
    model = models.ForeignKey(Model, on_delete=models.CASCADE)
    description = models.TextField()

    def save(self, *args, **kwargs):
        if self.pk is None:  # create
            self.model = Model.objects.create( name = "some random name" )
        super().save(*args, **kwargs)  # Call the "real" save() method.

2) Option 2: Using pre-save signal:

from django.db.models.signals import pre_save
from django.dispatch import receiver    

@receiver(pre_save, sender=AnotherModel)
def my_handler(sender, **kwargs):
    if sender.pk is None:  # create
        sender.model = Model.objects.create( name = "some random name" )

Important:

The related model must be created before to save current one. In examples I used:

Model.objects.create( name = "some random name" )

But you can create model as a regular way:

m = Model()
m.name = "random name"
m.save()  # <--- important!

Upvotes: 7

Related Questions