views:

38

answers:

2

I'm looking for some advice/opinions on the best way to approach creating a sort-of-dynamic model in django.

The structure needs to describe data for Products. There are about 60 different possible data points that could be relevant, with each Product choosing about 20 of those points (with much overlapping) depending on its ProductType. There are about 2 dozen different ProductTypes, with each ProductType falling into one of 6 categories.

The obvious, but ungraceful method, would be to just put all 100 data points into the Product model, and just pick and choose, and ignore any fields left empty. Advantage: it's obvious. Disadvantage: it's ugly, and if I need to add more data points, it requires updating the database.

My thought is to make each product completely abstract, and only define its product-type, and a few other identifying traits.

class Product(models.Model):
    productType = models.ForeignKey(ProductType)

I would then have a separate models for each kind of data point (number, text, date, etc.) which would look like this:

class TextData(models.Model):
    fieldName = models.CharField(etc)
    verboseName = models.CharField(etc)
    data = models.CharField(etc)
    product = models.ForeignKey(Product)

Finally, I would make a model that defines what kinds of data are relevant for each product-type, and what each data point should be called.

class ProductType(models.Model):
    name = models.CharField(etc)
    ....

So the main question is: what would be the best way to fill out the relevant fields for a product type, when they can be varying? Perhaps another model that holds the name/type of a data point, and a ManyToManyField between ProductType and that model? A text field with XML? An outside XML field defining the structure? Abandon this entire pursuit and go with something better?

Thanks for any help!

+1  A: 

If you are looking for implementations of dynamic attributes for models in django in some kind of eav style, have a look at eav-django, or at django-expando.

lazerscience
+1  A: 

This is ordinary relational database design. Don't over-optimize it with OO and inheritance techniques.

You have a Product Category table with (probably) just names.

You have a Product Type table with not much information with FK's to category.

You have a Product table with an FK relationship to Product Type.

You have a Product Feature table with your data points and an FK to product.

To work with a Product, you query the product. If you need the features, you're just working with the "feature_set". Django fetches them for you.

This works remarkably well and is a well-established feature of a relational database and an ORM layer. The DB caching and the ORM caching make these queries go very quickly.

S.Lott