鉴于Django模型喜欢:
from django.db import models
class MyModel(models.Model):
textfield = models.TextField()
如何在textfield
上自动压缩save()
(例如使用zlib
)并在访问属性textfield
时解压缩(即未加载),工作流程如下:
m = MyModel()
textfield = "Hello, world, how are you?"
m.save() # compress textfield on save
m.textfield # no decompression
id = m.id()
m = MyModel.get(pk=id) # textfield still compressed
m.textfield # textfield decompressed
我倾向于认为你会重载MyModel.save
,但我不知道保存时元素的就地修改模式。我也不知道Django在访问字段时解压缩的最佳方法(重载__getattr__
?)。
或者更好的方法是拥有custom field type?
我确定我已经看到了一个几乎就是这样的例子,但是我最近还是找不到它。
感谢您阅读 - 以及您可能提供的任何输入。
答案 0 :(得分:2)
自定义字段类型绝对是这里的方式。这是确保在保存时压缩字段并在加载时解压缩的唯一可靠方法。确保按照链接中的描述设置元类。
答案 1 :(得分:2)
您需要在自定义字段类型中实施to_python和get_prep_value,以分别解压缩和压缩数据。
答案 2 :(得分:1)
答案 3 :(得分:0)
另见https://djangosnippets.org/snippets/2014/ 看起来有点容易......仍然只是一个TextField。
class CompressedTextField(models.TextField):
"""
model Fields for storing text in a compressed format (bz2 by default)
"""
__metaclass__ = models.SubfieldBase
def to_python(self, value):
if not value:
return value
try:
return value.decode('base64').decode('bz2').decode('utf-8')
except Exception:
return value
def get_prep_value(self, value):
if not value:
return value
try:
value.decode('base64')
return value
except Exception:
try:
tmp = value.encode('utf-8').encode('bz2').encode('base64')
except Exception:
return value
else:
if len(tmp) > len(value):
return value
return tmp
答案 4 :(得分:0)
我想值得一提的是PostgreSQL默认压缩所有字符串类型:Text compression in PostgreSQL
所以也许答案是:不是吗?