# just a demo example
# the actual code is at http://gist.github.com/608595
from django.db import models
from polymorphic import polymorphic_manager
class Player(models.Model):
hitpoints = models.PositiveIntegerField(default=100)
# polymorphic_on field
race = models.SmallIntegerField(choices=enumerate(['Elf', 'Troll', 'Human']))
# keep the default (non-polymorphic) manager
objects = models.Manager()
# a new manager polymorphic on Player.race
objects_by_race = polymorphic_manager(on=race)
def __unicode__(self):
return u'Player(%s)' % self.pk
class Elf(Player):
bows = models.PositiveIntegerField(default=0)
# polymorphic manager for race=0
objects = Player.objects_by_race.polymorphic_identity(0)
def __unicode__(self):
return u'Elf(%s)' % self.pk
class Troll(Player):
axes = models.PositiveIntegerField(default=0)
# polymorphic manager for race=1
objects = Player.objects_by_race.polymorphic_identity(1)
def __unicode__(self):
return u'Troll(%s)' % self.pk
class Human(Player):
# polymorphic manager for race=2
objects = Player.objects_by_race.polymorphic_identity(2)
class Meta:
proxy = True
def __unicode__(self):
return u'Human(%s)' % self.pk
def test():
from random import choice
Player.objects.all().delete()
# create a bunch of random type players
for i in xrange(10):
choice([Elf, Troll, Human]).objects.create()
# retrieval through the polymorphic manager returns instances of the right class
print "Automatically downcast players:", Player.objects_by_race.all()
# retrieval through default Player manager returns Player instances as usual
players = Player.objects.all()
print "Non-downcast players:", players
# but they can be explicitly downcast to the right class
print "Explicitly downcast players:", map(Player.objects_by_race.downcast, players)
# retrieving the instances of a specific class works as expected
print "Elfs:", Elf.objects.all()
print "Trolls:", Troll.objects.all()
print "Humans:", Human.objects.all()
test()
Comments