Django - 从TextField获取字典

时间:2017-10-03 10:49:15

标签: python django class django-models

我想在Django中存储一个字典。 一个非常基本的解决方案是:

class foo(models.Model):
    bar = models.TextField()

fooInstance.bar = json.dumps(my_dict)

但我希望能够直接访问它而不是经常使用json,所以我做了以下内容:

class foo(models.Model):
    _bar = models.TextField()

    @property
    def bar(self):
        import json
        return json.loads(self._bar)

    @bar.setter
    def bar(self, new_bar):
        import json
        self._bar = json.dumps(new_bar)

fooInstance.bar = my_dict

这在很大程度上起作用,只是我不能做一件事:

fooInstance.bar['key'] = 'value'

这个表达式通过,没有错误。但是没有设定价值。 有没有人对如何做到这一点有任何想法?

感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

虽然最好使用JSONField为您处理,但我会回答您的问题,因为不是强制执行特定的数据库后端。

问题的根本原因是,每次在模型实例上调用bar时,都会创建并返回一个新字典,因此您的更改将会丢失。

您应该将创建的字典存储在属性中以避免这种重新创建行为。

class foo(models.Model):
    _bar = models.TextField()

    def get_bar(self):
        dict_value = getattr(self, '_bar_dict', None)
        if not dict_value:
            import json
            dict_value = json.loads(self._bar)
            setattr(self, '_bar_dict', dict_value)
        return dict_value

    def set_bar(self, new_bar):
        import json
        self._bar = json.dumps(new_bar)
        self._bar_dict = dict(new_bar)

    bar = property(get_bar, set_bar)

或者你可以使用@cached_property装饰者。 [见12]

答案 1 :(得分:0)

因此,无需在每次更改为bar时更新_bar,只能在保存之前更改_bar。 这是我的修复:

class foo(models.Model)
    _bar = models.TextField()

        def __getattr__(self, attr):
            if attr == 'bar':
                import json
                try:
                    self.bar = json.loads(self._bar)
                except ValueError:
                    return {}
                return self.bar
            else:
                return super(foo, self).__getattr__(self, attr)

        def save(self):
            import json
            if hasattr(self, bar):
                self._bar = json.dumps(self.bar)
            super(foo, self).save()
这是有效的。我能够将fooInstance.bar作为常规字典使用,并将其保存到数据库中。