Django HStore:如何覆盖键值模型字段的 __getattr__ 和 __setattr__
Posted
技术标签:
【中文标题】Django HStore:如何覆盖键值模型字段的 __getattr__ 和 __setattr__【英文标题】:Django HStore: How to override a key-value model field's __getattr__ and __setattr__ 【发布时间】:2013-12-10 17:03:46 【问题描述】:通过django-hstore
module,在 Django 中使用 hstore 时,我的脚已经湿透了。使用hstore
的一大优势是它允许将键值存储在字段中,同时在 Postgresql 中提供良好的索引。 django-hstore
(和一般的hstore
)的一大缺点是您只能将值存储为字符串。
为了克服这个问题,我认为最好覆盖模型字段 (hstore.DictionaryField
),这样输入到该字段的任何数据都会自动以 JSON 编码,检索到的任何数据都会自动从 JSON 解码。我试图通过覆盖__setattr__
方法来做到这一点,但这会导致大量错误(当正在设置该字段的所有属性时)。有什么正确方法的想法吗?
到目前为止我所做的(我在关注 setter 的同时注释掉了 getter 部分,但留下了它以显示我的想法):
import simplejson as json
from django.db import models
from django_hstore import hstore
def _unpack_json(value):
try:
value = json.loads(value)
except TypeError:
pass
return value
class HStoreJsonDict(hstore.DictionaryField):
@staticmethod
def _load_json(value):
try:
value = json.dumps(value)
except Exception as e:
# Is this needed?
print(value, e)
pass
return value
# def __getattribute__(self, key):
# print('__getattribute__')
# value = super(HStoreJsonDict, self).__getattribute__(key)
# return _unpack_json(value)
# def __getitem__(self, key):
# print('__getitem__')
# value = super(HStoreJsonDict, self).__getitem__(key)
# return _unpack_json(value)
def __setattr__(self, key, value):
print('__setattr__', key, value)
value = self._load_json(value)
return super(HStoreJsonDict, self).__setattr__(key, value)
class TestModel(models.Model):
name = models.CharField(max_length=64)
data = HStoreJsonDict(db_index=True)
objects = hstore.HStoreManager()
def __unicode__(self):
return '%s - %s' % (self.name, self.data)
【问题讨论】:
【参考方案1】:归根结底,我发现最容易派生出django-hstore
模块并将序列化/反序列化放在DictionaryField
的get_prep_value()
和to_python()
方法中(see here for code)。
对于其他希望在使用 Django 时操作数据库的入口/检索数据的人,我强烈建议您查看 Django 的文档 to_python() 和 get_prep_value()。
【讨论】:
以上是关于Django HStore:如何覆盖键值模型字段的 __getattr__ 和 __setattr__的主要内容,如果未能解决你的问题,请参考以下文章
如何创建作为多个查询联合的 Django 模型字段,以实现覆盖字段?
如何在 django rest 框架 ModelSerializer 中覆盖模型字段验证