Reputation: 6408
I've been trying to figure this out for a while now with little success. I'm attempting to write a class factory that plays nice with Django's ORM, so that I can take a model schema like this:
Product
SubclassOfProduct0
SubclassOfProduct1
....
To work like this:
Product.objects.get(pk=7) // returns the result of SubclassOfProduct0(pk=7)
Product.objects.filter(propname="w00t") // returns a QuerySet of Product objects
So I was thinking something like this:
class ProductManager(models.Manager):
def get(self, *a, **kwa):
# Get the id from Products (somehow)
if product.type == Product.TYPE_SUBCLASS0:
return ProductSubClass0.objects.get(pk=kwa["pk"])
class Product(models.Model):
TYPE_SUBCLASS0 = 0
TYPE_SUBCLASS1 = 1
objects = ProductManager()
def __init__(self, *a, **kwa):
self.set_defaults()
def set_defaults(self):
pass
class ProductSubClass0(models.Model):
def set_defaults(self):
self.type == self.TYPE_SUBCLASS0
...but I don't know how to do it "right". Can someone shed some light here?
Upvotes: 1
Views: 3245
Reputation: 321
You could use entity framework with generic relations. For example, in models.py:
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
# Product
class Product(models.Model):
name = models.CharField(max_length=128)
pub_date = models.DateTimeField('date published', null=True)
productDescription = models.CharField(max_length=400)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
#Shirt Product type
class ShirtProduct(models.Model):
product = generic.GenericRelation(Product)
#Book Product type
class BookProduct(models.Model):
product = generic.GenericRelation(Product)
....
For search one product id, you can use this method in your ProductManager: product = generic.GenericRelation(Product, content_type_field='content_type_fk', object_id_field='object_primary_key')
(reverse generic relations in the same section of djangoproject page)
Upvotes: 0
Reputation: 329
You could just subclass your Product
, as documented here: http://docs.djangoproject.com/en/1.2/topics/db/models/#model-inheritance
class OtherProduct(Product):
battery_life = …
Maybe also make Product
an abstract base class if you don’t need to use it directly.
Upvotes: 0
Reputation: 1803
Django Tagging has a great example in the models.py as to how it figures out the content type of specific classes. I'm currently using the pattern in another module I developed with permissions.
Upvotes: 2