views:

161

answers:

2

Say I have models:

class Animal(models.Model):
    type = models.CharField(max_length=255)

class Dog(Animal):
    def make_sound(self):
        print "Woof!"
    class Meta:
        proxy = True

class Cat(Animal):
    def make_sound(self):
        print "Meow!"
    class Meta:
        proxy = True

Let's say I want to do:

 animals = Animal.objects.all()
 for animal in animals:
     animal.make_sound()

I want to get back a series of Woofs and Meows. Clearly, I could just define a make_sound in the original model that forks based on animal_type, but then every time I add a new animal type (imagine they're in different apps), I'd have to go in and edit that make_sound function. I'd rather just define proxy models and have them define the behavior themselves. From what I can tell, there's no way of returning mixed Cat or Dog instances, but I figured maybe I could define a "get_proxy_model" method on the main class that returns a cat or a dog model.

Surely you could do this, and pass something like the primary key and then just do Cat.objects.get(pk = passed_in_primary_key). But that'd mean doing an extra query for data you already have which seems redundant. Is there any way to turn an animal into a cat or a dog instance in an efficient way? What's the right way to do what I want to achieve?

A: 

You can perhaps make Django models polymorphic using the approach described here. That code is in early stages of development, I believe, but worth investigating.

Vinay Sajip
A: 

These two blog posts I wrote: http://alexgaynor.net/search/?q=poly can be adapted to work with proxy inheritance fair easily (the big point to take away is the metaclass approach for automatic class repalcement).

Alex Gaynor