Django在save()上自动压缩Model Field,并在访问字段时解压缩

时间:2010-03-31 15:34:17

标签: django django-orm compression django-models

鉴于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

我确定我已经看到了一个几乎就是这样的例子,但是我最近还是找不到它。

感谢您阅读 - 以及您可能提供的任何输入。

5 个答案:

答案 0 :(得分:2)

自定义字段类型绝对是这里的方式。这是确保在保存时压缩字段并在加载时解压缩的唯一可靠方法。确保按照链接中的描述设置元类。

答案 1 :(得分:2)

您需要在自定义字段类型中实施to_pythonget_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

所以也许答案是:不是吗?