Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to store arbitrary name/value key pairs in a Django model?

I have a fixed data model that has a lot of data fields.

class Widget(Models.model):
    widget_owner = models.ForeignKey(auth.User)
    val1 = models.CharField()
    val2 = models.CharField()
    ...
    val568 = ...

I want to cram even more data into this Widget by letting my users specify custom data fields. What's a sane way to do this? Is storing name/value pairs where the user can specify additional "Widget fields" a good idea? My pseudo thoughts are below:

data_types = ('free_text', 'date', 'integer', 'price')
class CustomWidgetField(models.Model)
  owner = ForeignKey(auth.User)
  field_title = models.CharField(auth.User)
  field_value_type = models.CharField(choices = data_types)

class CustomWidgetValue(models.Model)
  field_type = ForeignKey(CustomWidgetField)
  widget = ForeignKey(Widget)
  value = models.TextField()

So I want to let each user build a new type of data field that will apply to all of their widgets and then specify values for each custom field in each widget. I will probably have to do filtering/searching on these custom fields just as I would on a native field (which I assume will be much slower than operating on native fields.) But the scale is to have a few dozen custom fields per Widget and each User will only have a few thousand Widgets in their inventory. I can also probably batch most of the searching/filtering on the custom fields into a backend script (maybe.)

like image 463
MikeN Avatar asked Oct 29 '09 00:10

MikeN


People also ask

Can Django model have two primary keys?

Do Django models support multiple-column primary keys? ¶ No. Only single-column primary keys are supported.

Should Django model names be plural?

It is generally recommended to use singular nouns for model naming, for example: User, Post, Article. That is, the last component of the name should be a noun, e.g.: Some New Shiny Item. It is correct to use singular numbers when one unit of a model does not contain information about several objects.

What is primary key in Django model?

If you'd like to specify a custom primary key, specify primary_key=True on one of your fields. If Django sees you've explicitly set Field. primary_key , it won't add the automatic id column. Each model requires exactly one field to have primary_key=True (either explicitly declared or automatically added).


2 Answers

Consider representing all custom properties with serialized dict. I used this in a recent project and it worked really well.

 class Widget(models.Model):
      owner = models.ForeignKey(auth.User)
      props = models.TextField(blank=True) # serialized custom data

      @property
      def props_dict(self):
          return simplejson.loads(self.props)

 class UserProfile(models.Model)
      user = models.ForeignKey(auth.User)
      widget_fields = models.TextField(blank=True) # serialized schema declaration
like image 74
Alexander Lebedev Avatar answered Oct 01 '22 20:10

Alexander Lebedev


It looks like you've reinvented the triple store. I think it's a common thing, as we follow the idea of database flexibility to its natural conclusion. Triple stores tend to be fairly inefficient in relational database systems, but there are systems designed specifically for them.

http://en.wikipedia.org/wiki/Triplestore

At the scales you're talking about, your performance is likely to be acceptable, but they don't generally scale well without a specialized DB.

like image 25
Paul McMillan Avatar answered Oct 01 '22 19:10

Paul McMillan