Django's post_save signal behaves weirdly with models using multi-table inheritance
I am noticing an odd behavior in the way Django's post_save signal works when using a model that has multi-table inheritance.
I have these two models:
class Animal(models.Model):
category = models.CharField(max_length=20)
class Dog(Animal):
color = models.CharField(max_length=10)
I have a post save callback called echo_category:
def echo_category(sender, **kwargs):
print "category: '%s'" % kwargs['instance'].category
post_save.connect(echo_category, sender=Dog)
I have this fixture:
[
{
"pk": 1,
"model": "animal.animal",
"fields": {
"category": "omnivore"
}
},
{
"pk": 1,
"model": "animal.dog",
"fields": {
"color": "brown"
}
}
]
In every part of the program except for in the post_save callback the following is true:
from animal.models import Dog
Dog.objects.get(pk=1).category == u'omnivore' # True
When I run syncdb and the fixture is installed, the echo_category function is run. The output from syncdb is:
$ python manage.py syncdb --noinput
Installing json fixture 'initial_data' from '~/my_proj/animal/fixtures'.
category: ''
Installed 2 object(s) from 1 fixture(s)
The weird thing here is that the dog object's category attribute is an empty string. Why is it not 'omnivore' like it is everywhere else?
As a temporary (hopefully) workaround I reload the object from the database in the post_save callback:
def echo_category(sender, **kwargs):
instance = kwargs['instance']
instance = sender.objects.get(pk=instance.pk)
print "category: '%s'" % instance.category
post_save.connect(echo_category, sender=Dog)
This works but it is not something I like because I must remember to do it when the model inherits from another model and it must hit the database again. The other weird thing is that I must do instance.pk to get the primary key. The normal 'id' attribute does not work (I cannot use instance.id). I do not know why this is. Maybe this is related to the reason why the category attribute is not doing the right thing?