Type Polymorphism in Django
Monday, May 24, 2010 11:15 p.m.
models.py
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
related_object_limits = {'model__in': ('specificitem1', \
'specificitem2')}
class RelatedItem(models.Model):
content_type = models.ForeignKey(ContentType, \
related_name='main_object', \
limit_choices_to=related_object_limits)
object_id = models.PositiveIntegerField()
content_object = \
generic.GenericForeignKey('content_type', \
'object_id')
related_content_type = \
models.ForeignKey(ContentType, \
related_name='related_object', \
limit_choices_to=related_object_limits)
related_object_id = models.PositiveIntegerField()
related_object = \
generic.GenericForeignKey('related_content_type', \
'related_object_id')
class Item(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField(unique=True)
related = generic.GenericRelation(RelatedItem, \
content_type_field='content_type', \
object_id_field='object_id')
def __unicode__(self):
return self.name
class Meta:
abstract = True
class SpecificItem1(Item):
property1 = models.CharField(max_length=100)
class SpecificItem2(Item):
property2 = models.CharField(max_length=100)
admin.py
from django.contrib import admin
from django.contrib.contenttypes.generic \
import GenericTabularInline
from models import SpecificItem1
class RelatedItemInline(GenericTabularInline):
model = RelatedItem
class SpecificItem1Admin(admin.ModelAdmin):
list_display = ('name', 'slug')
search_fields = ('name',)
inlines = [RelatedItemInline,]
admin.site.register(SpecificItem1, SpecificItem1Admin)
