Reputation: 3897
I have these models:
class MyModel1(models.Model):
field1 = models.CharField(max_length=128, blank=True, null=True)
fieldrelated1 = models.OneToOneField('MyModel2', max_length=128, blank=True, null=True, related_name='mymodel2')
fieldrelated2 = models.OneToOneField('MyModel3', max_length=128, blank=True, null=True, related_name='mymodel3')
fieldrelated3 = models.OneToOneField('MyModel4', max_length=128, blank=True, null=True, related_name='mymodel4')
class MyModel2(models.Model):
field2 = models.CharField(max_length=128, blank=True, null=True)
myfk = models.ForeignKey(MyModel1, max_length=128, blank=True, null=True)
class MyModel3(models.Model):
field3 = models.CharField(max_length=128, blank=True, null=True)
test = models.CharField(max_length=128, blank=True, null=True)
class MyModel4(models.Model):
field4 = models.CharField(max_length=128, blank=True, null=True)
test = models.CharField(max_length=128, blank=True, null=True)
Then, this method:
def create_child_objects(instance, created, rad, **kwargs):
if not created or rad:
return
field1 = instance.field1
if not instance.fieldrelated1_id:
fieldrelated1, _ = MyModel2.objects.get_or_create(field1=field2)
instance.fieldrelated1 = fieldrelated1
if not instance.fieldrelated2_id:
fieldrelated2, _ = MyModel3.objects.get_or_create(field1=field3)
instance.fieldrelated2 = fieldrelated2
if not instance.fieldrelated3_id:
fieldrelated3, _ = MyModel4.objects.get_or_create(field1=field4)
instance.fieldrelated3 = fieldrelated3
instance.save()
models.signals.post_save.connect(create_child_records, sender=MyModel1, dispatch_uid='create_child_objects')
So far, this method works to save the parent and save particular fields on child creation.
My problem comes when I want to, for example, instead of saving a parent's CharField
into a child CharField
, I want to save the actual parent instance into a child's ForeignKey
field, like this:
def create_child_objects(instance, created, rad, **kwargs):
if not created or rad:
return
field1 = instance.__str__
if not instance.fieldrelated1_id:
fieldrelated1, _ = MyModel2.objects.get_or_create(field1=myfk)
instance.fieldrelated1 = fieldrelated1
if not instance.fieldrelated2_id:
fieldrelated2, _ = MyModel3.objects.get_or_create(field1=field3)
instance.fieldrelated2 = fieldrelated2
if not instance.fieldrelated3_id:
fieldrelated3, _ = MyModel4.objects.get_or_create(field1=field4)
instance.fieldrelated3 = fieldrelated3
instance.save()
models.signals.post_save.connect(create_child_objects, sender=MyModel1, dispatch_uid='create_child_records')
The parent object is saved into db with a method like this:
def __str__(self):
return ('{}: {}: {}'.format(self.field1, self.field2, self.field3))
So, after the second create_child_objects
it throws me this:
TypeError at /admin/mymodel/instance/add/
int() argument must be a string, a bytes-like object or a number, not 'method'
So, how can I save the parent object descriptor into a ForeignKey
field to the parent object?
EDIT
What is saved on this myfk
field is the id of MyModel1
, so, it would be sufficient to save this, but when I try like this field1 = MyModel1.id
It says:
ValueError at /admin/mymodel/instance/add/
Cannot assign "98": "MyModel2.field1.id" must be a "MyModel1" instance.
Upvotes: 0
Views: 46
Reputation: 9299
field1 = instance.__str__
change to
field1 = instance.__str__()
or
field1 = str(instance)
__str__
is a method so your assignment makes field1
pointing to this method, not method's result.
All the MyModel[2-4].objects.get_or_create(field1=field2)
lines are wrong:
field1
field, so correct filter would be field[2-4]=field1
__str__
method is a combination of those IDs and this string must be parsed first; only extracted values would matchAnd I don't understand how your __str__
method works since this model does not have field2
, field3
and field4
.
I suggest you to rethink the approach. Have a look at generic relations.
Upvotes: 1