3

给定一个 Django 模型,如下所示:

from django.db import models

class MyModel(models.Model):
    textfield = models.TextField()

如何在访问属性(即不加载)时自动压缩textfield(例如使用zlib)并解压缩它,工作流程如下:save()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__?)。

或者更好的方法是使用自定义字段类型

我确信我已经看到了一个几乎完全一样的例子,但可惜我最近没能找到它。

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

4

4 回答 4

2

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

于 2010-03-31T16:33:05.963 回答
2

您需要在自定义字段类型中实现to_pythonget_prep_value以分别解压缩和压缩数据。

于 2010-04-04T11:44:02.973 回答
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
于 2016-05-04T19:59:47.950 回答
0

我想值得一提的是 PostgreSQL 默认压缩所有字符串类型:Text compression in PostgreSQL

所以也许答案是:不要?

于 2020-07-22T04:35:56.943 回答