Django's post_save signal behaves weirdly with models using multi-table inheritance

Posted by hekevintran on Stack Overflow See other posts from Stack Overflow or by hekevintran
Published on 2010-04-09T02:42:40Z Indexed on 2010/04/09 19:33 UTC
Read the original article Hit count: 397

Filed under:
|

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?

© Stack Overflow or respective owner

Related posts about django

Related posts about django-models