How to store a dictionary on a Django Model?

前端 未结 13 913
广开言路
广开言路 2020-11-28 23:24

I need to store some data in a Django model. These data are not equal to all instances of the model.

At first I thought about subclassing the model, but I’m trying t

相关标签:
13条回答
  • 2020-11-29 00:04

    Django-Geo includes a "DictionaryField" you might find helpful:

    http://code.google.com/p/django-geo/source/browse/trunk/fields.py?r=13#49

    In general, if you don't need to query across the data use a denormalized approach to avoid extra queries. User settings are a pretty good example!

    0 讨论(0)
  • 2020-11-29 00:05

    I agree that you need to refrain stuffing otherwise structured data into a single column. But if you must do that, Django has an XMLField build-in.

    There's also JSONField at Django snipplets.

    0 讨论(0)
  • 2020-11-29 00:07

    I'm not sure exactly sure of the nature of the problem you're trying to solve, but it sounds curiously similar to Google App Engine's BigTable Expando.

    Expandos allow you to specify and store additional fields on an database-backed object instance at runtime. To quote from the docs:

    import datetime
    from google.appengine.ext import db
    
    class Song(db.Expando):
      title = db.StringProperty()
    
    crazy = Song(title='Crazy like a diamond',
                 author='Lucy Sky',
                 publish_date='yesterday',
                 rating=5.0)
    
    crazy.last_minute_note=db.Text('Get a train to the station.')
    

    Google App Engine currently supports both Python and the Django framework. Might be worth looking into if this is the best way to express your models.

    Traditional relational database models don't have this kind of column-addition flexibility. If your datatypes are simple enough you could break from traditional RDBMS philosophy and hack values into a single column via serialization as @Ned Batchelder proposes; however, if you have to use an RDBMS, Django model inheritance is probably the way to go. Notably, it will create a one-to-one foreign key relation for each level of derivation.

    0 讨论(0)
  • 2020-11-29 00:12

    I use a textfield and json.loads()/json.dumps()

    models.py
    
    import json
    from django.db import models
    
    class Item(models.Model):
        data = models.TextField(blank=True, null=True, default='{}')
    
        def save(self, *args, **kwargs):
            ## load the current string and
            ## convert string to python dictionary
            data_dict = json.loads(self.data)
    
            ## do something with the dictionary
            for something in somethings:
                data_dict[something] = some_function(something)
    
            ## if it is empty, save it back to a '{}' string,
            ## if it is not empty, convert the dictionary back to a json string
            if not data_dict:
                self.data = '{}'
            else:
                self.data = json.dumps(data_dict)
    
    
            super(Item, self).save(*args, **kwargs)
    
    
    0 讨论(0)
  • 2020-11-29 00:13

    Being "not equal to all instances of the model" sounds to me like a good match for a "Schema-free database". CouchDB is the poster child for that approach and you might consider that.

    In a project I moved several tables which never played very nice with the Django ORM over to CouchDB and I'm quite happy with that. I use couchdb-python without any of the Django-specific CouchDB modules. A description of the data model can be found here. The movement from five "models" in Django to 3 "models" in Django and one CouchDB "database" actually slightly reduced the total lines of code in my application.

    0 讨论(0)
  • 2020-11-29 00:17

    If it's really dictionary like arbitrary data you're looking for you can probably use a two-level setup with one model that's a container and another model that's key-value pairs. You'd create an instance of the container, create each of the key-value instances, and associate the set of key-value instances with the container instance. Something like:

    class Dicty(models.Model):
        name      = models.CharField(max_length=50)
    
    class KeyVal(models.Model):
        container = models.ForeignKey(Dicty, db_index=True)
        key       = models.CharField(max_length=240, db_index=True)
        value     = models.CharField(max_length=240, db_index=True)
    

    It's not pretty, but it'll let you access/search the innards of the dictionary using the DB whereas a pickle/serialize solution will not.

    0 讨论(0)
提交回复
热议问题