Django:通过类似dict的接口访问表

时间:2016-10-10 13:00:34

标签: python django django-models

所以我在Django的情况下,我有一个名为S的模型,它可以有一系列属性,但我现在不知道哪些属性是相关/需要的。为了处理这个问题,我正在考虑创建一个额外的模型SAttrib,它模仿字典条目并通过元数据属性访问它。见下文。

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'),)

我想通过将其作为属性实现来访问存储在SAttrib中的属性。所以我可以像这样访问值:

y = S.objects.get()
y.metadata["foo"]

然后它变得一团糟,需要大量额外的代码来设置和保存对象/包含等。

s = S.objects.get()
s.metadata["foo"] = "spam"

.....

有没有更好的方法来构建这个或者已经存在于Django中的东西,我错过了?

欢迎所有建议......

由于

1 个答案:

答案 0 :(得分:1)

这个想法并没有太大的错误,除了你似乎已经使用_get_metadata函数使它变得不必要地复杂化了。由于它,你可能会遇到一些性能问题。

当你事先不知道你将在桌面上存储什么类型的名称/值对时,这种双表方法在很多网络应用程序中非常流行。然而,由于nosql解决方案和大多数RDBMS现在支持JSON数据类型,这种做法现在正在下降。

Django内置了对Postgresql优秀JSONB字段的支持。对于其他数据库,经过试验和测试的JSONField可用,因此使用JSONFields可以为您提供非常好的数据库独立解决方案。