Reputation: 71
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
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
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