views:

919

answers:

4

Hi fellow stackers,

I'd like to ask about the most elegant approach when it comes to designing models with virtual fields such as below in Django...

Let's say we're building an online store and all the products in the system are defined by the model "Product".

class Product(models.Model):
    # common fields that all products share
    name = ...
    brand = ...
    price = ...

But the store will have lots of product types completely unrelated with eachother, so I need some way to store those virtual fields of different product types (ie. capacity of a MP3 player, pagecount of a book,..).

The solutions I could come up with my raw Django skills are far from perfect so far:

  • Having a "custom_fields" property and intermediate tables that I manage manually. (screaming ugly in my face :))

  • Or inheriting classes from "Product" on the fly with Python's dangerous exec-eval statements (that is too much voodoo magic for maintenance and also implementation would require knowledge of Django internals).

What's your take on this?

TIA.

+1  A: 

Ruby on Rails has a "serialized" field which allows you to pack a dictionary into a text field. Perhaps DJango offers something similar?

This article has an implementation of a SerializedDataField.

epochwolf
+10  A: 

Products have Features.

class Feature( models.Model ):
    feature_name = models.CharField( max_length=128 )
    feature_value = models.TextField()
    part_of = models.ForeignKey( Product )

Like that.

Just a list of features.

p= Product( "iPhone", "Apple", 350 )
p.save()
f= Feature( "mp3 capacity", "16Gb", p )
f.save()

If you want, you can have a master list of feature names in a separate table. Don't over-analyze features. You can't do any processing on them. All you do is present them.

S.Lott
An abstract model with the common fields is also a useful way to handle this.
James Bennett
+1  A: 

Personally, I'd go with S. Lott's answer. However, you might want to create a custom JSON Field:

http://svn.navi.cx/misc/trunk/djblets/djblets/util/fields.py

http://www.djangosnippets.org/snippets/377/

Tiago
A: 

Go with the inheritance. Create Produce subclasses with their own, additional fields.

ironfroggy