views:

543

answers:

2

Hi, I have a problem with serialization of Django inherited models. For example

class Animal(models.Model):
    color = models.CharField(max_length=50)

class Dog(Animal):
    name = models.CharField(max_length=50)

...
# now I want to serialize Dog model with Animal inherited fields obviously included
print serializers.serialize('xml', Dog.objects.all())

and only Dog model has been serialized.

I can do smth like

all_objects = list(Animal.objects.all()) + list(Dog.objects.all())
print serializers.serialize('xml', all_objects)

But it looks ugly and because my models are very big so I have to use SAX parser and with such output it's difficult to parse.

Any idea how to serialize django models with parent class?

**EDIT: ** It use to work ok before this patch has been applied. And the explanation why the patch exist "Model saving was too aggressive about creating new parent class instances during deserialization. Raw save on a model now skips saving of the parent class. " I think there should be an option to be able to serialize "local fields only" by default and second option - "all" - to serialize all inherited fields.

A: 

Did you look at select_related() ? as in

serializers.serialize('xml', Dog.objects.select_related().all())
Steven H.
This doesn't help: `select_related` does not affect the django serializer's handling of parent models.
Wogan
`select_related` is an optimization. No extra data is returned by the QuerySet. It just uses (potentially) fewer SQL queries to get any referenced data.In the case above, there are no references through `Dog` or `Animal` to other models, so there's absolutely no benefit to using `select_related()`.
Matt S.
+1  A: 

You found your answer in the documentation of the patch.

all_objects = list(Animal.objects.all()) + list(Dog.objects.all())
print serializers.serialize('xml', all_objects)

However, if you change Animal to be an abstract base class it will work:

class Animal(models.Model):
    color = models.CharField(max_length=50)

    class Meta:
        abstract = True

class Dog(Animal):
    name = models.CharField(max_length=50)

This works as of Django 1.0. See http://docs.djangoproject.com/en/dev/topics/db/models/.

Matt S.