2

首先,我知道有很多类似的问题,但其他解决方案不包括我的具体情况:

在我的 sqlite-database 中有现有的二进制数据(SHA1 和类似的哈希)。通过谷歌搜索和阅读django-docs我想出了以下内容:

import base64

class BlobField(models.Field):
""" 
Stores raw binary data
"""

description = 'Stores raw binary data'
__metaclass__ = models.SubfieldBase

def __init__(self, *args, **kwds):
    super(BlobField, self).__init__(*args, **kwds)

def get_internal_type(self):
    return "BlobField"

def get_db_prep_value(self, value, connection=None, prepared=False):
    return base64.decodestring(value)

def to_python(self, value):
    return base64.encodestring(value)

这是我想要的,值在正确的时刻被编码和解码,但是在将模型保存到数据库中时,它给了我以下错误:

DatabaseError:您不得使用 8 位字节串,除非您使用可以解释 8 位字节串的 text_factory(如 text_factory = str)。强烈建议您将应用程序切换为 Unicode 字符串。

我怎样才能解决这个问题?(可能不会破坏我在应用程序其余部分的所有 unicode 兼容性)

我无法更改 db-columns 的格式,因为数据被另一个应用程序使用。


编辑:正如@filip-dupanovic 所建议的,我采用了 BinaryField 类,如下所示:

class BinaryField(models.Field): description = _("原始二进制数据")

def __init__(self, *args, **kwargs):
    kwargs['editable'] = False
    super(BinaryField, self).__init__(*args, **kwargs)
    if self.max_length is not None:
        self.validators.append(validators.MaxLengthValidator(self.max_length))

def get_internal_type(self):
    return "BinaryField"

def get_default(self):
    if self.has_default() and not callable(self.default):
        return self.default
    default = super(BinaryField, self).get_default()
    if default == '':
        return b''
    return default

def get_db_prep_value(self, value, connection, prepared=False):
    #value = super(BinaryField, self
    #    ).get_db_prep_value(value, prepared, connection=connection)
    #if value is not None:
    #    return connection.Database.Binary(value)
    return value

请注意我必须在 处插入的注释get_db_prep_value(),就像这样,它按预期工作,如果我取消注释这些行,我会收到错误

TypeError:get_db_prep_value() 为关键字参数“连接”获取了多个值

我可以忍受这一点,但不完全理解将其排除在外的含义。即使没有调用它仍然可以工作super()吗?

4

2 回答 2

1

不久前关闭的工单#2417BinaryField ,添加了一个模型字段。您应该查看此提交,特别是与如何将内部BlobField字段类型映射到数据库支持的适当类型相关的更改。

于 2013-03-18T16:13:01.657 回答
0
def get_db_prep_value(self, value, connection, prepared=False):
    value = super(BinaryField, self
        ).get_db_prep_value(value, connection, prepared)
    if value is not None:
        return connection.Database.Binary(value)
    return value
于 2013-03-19T10:10:04.333 回答