Reputation: 1227
I have a class which has two children
class MyChild1(models.Model):
attr1 = models.CharField(default='default value')
class MyChild2(models.Model):
pass
class MyParent(models.Model):
child1 = models.ForeignKey(Child1)
child2 = models.ForeignKey(Child2)
In my package, I require the value of attr1 - and in order to make sure it exists, I initialize the parent with a signal:
def init_my_parent(sender, *args, **kwargs):
child1 = MyChild1()
child2 = MyChild2()
signals.pre_init.connect(init_my_parent,sender=MyParent)
This seems to work fine to ensure that child1 and child2 are always instantiated. However, even when I manually set child1 and child2 (my_parent.child1 = child1
etc), child1_id
and child2_id
do not get set and the db throws an error
django.db.utils.IntegrityError: NOT NULL constraint failed: myparent.child1
I'm wondering what is causing this behavior? Somehow connecting that signal is causing a problem, but I'm not sure why. Here is a script similar to what I'm using:
c1 = MyChild1()
c2 = MyChild2()
c1.save()
c2.save()
p = MyParent()
p.child1 = c1
p.child2 = c2
p.save()
# Error thrown
Both of the values set in init_my_parent
should be overwritten above, and thus everything should work the same as if the signal function wasn't there?
Upvotes: 0
Views: 765
Reputation: 2242
The problem is that pre_init
signal doesn't take instance parameter, so you are editing actual class (sender
). Try using post_init
signal which takes instance
parameter, so you can change it:
def init_my_parent(sender, instance, *args, **kwargs):
if not hasattr(instance,'child1'):
instance.child1 = MyChild1()
instance.child1.save()
if not hasattr(instance,'child2'):
instance.child2 = MyChild2()
instance.child2.save()
signals.post_init.connect(init_my_parent, sender=MyParent)
Upvotes: 1
Reputation: 14
class MyChild1(models.Model):
attr1 = models.CharField(default='default value', max_length=100)
class MyChild2(models.Model):
pass
class MyParent(models.Model):
child1 = models.ForeignKey(MyChild1)
child2 = models.ForeignKey(MyChild2
using class instead of def, then it is going to be fine.
Upvotes: 0