Django: accessing a table via dict-like interface
<p>So I have situation in Django where I have a model called S which can have a series of attributes, but I have no idea currently what attributes will be relevant/required. In order to handle this I am thinking of creating a additional model SAttrib which mimics a dictionary entry and accessing it via a metadata property. See below. </p>

<pre><code>class S(models.Model):                                                                                                                                               
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=128, blank=True, null=True)
    description = models.CharField(max_length=128, blank=True, null=True)
    created_date = models.DateTimeField(auto_now_add=True, auto_now=False)
    modified_date = models.DateTimeField(auto_now_add=False, auto_now=True)
    def __unicode__(self):
        return smart_unicode(self.name)
    class Meta:
        db_table = "stest"
    def _get_metadata(self):
        class AD(dict):
            def __init__(self, id):
                self.id = id
            def __getitem__(self, key):
                return SampleAttrib.objects.filter(sample_id=self.id, attrib_key=key).get().attrib_value

        return AD(self.id)

    metadata = property(_get_metadata)

class SampleAttrib(models.Model):
    s_id = models.ForeignKey("S")
    attrib_key = models.CharField(max_length=128)
    attrib_value = models.TextField()
    class Meta:
        db_table = 's_attrib'
        unique_together = (('s_id', 'attrib_key'),)
</code></pre>

<p>I would like to make it so that I have access the attributes stored in SAttrib via implementing it as a property. So I would be able to access values like so:</p>

<pre><code>y = S.objects.get()
y.metadata["foo"]
</code></pre>

<p>But then it becomes a mess and requires a lot of additional code for setting and saving objects / contains etc. </p>

<pre><code>s = S.objects.get()
s.metadata["foo"] = "spam"

.....
</code></pre>

<p>Is there a better way of structuring this or something thats already in Django that I'm missing? </p>

<p>All suggestions welcome....</p>

<p>Thanks</p>

<p>Not a lot wrong with the idea, except for the fact that you seem to have made it needlessly complicated with the use of the <code>_get_metadata</code> function. You may be having a bit of a performance issue becaue of it as well.  </p>

<p>This kind of two-table approach is or rather was quite popular in many web apps when you don't know in advance what kind of name/value pairs you will be storing in your table. However the practice is now on the decline thanks to nosql solution and most RDBMS now supporting JSON data types.</p>

<p>Django has built in support for Postgresql's excellent JSONB field. For other databases, tried and tested JSONFields are available so using JSONFields would give you a pretty good database independent solution.</p>

python django django-models