首先,我知道有很多类似的问题,但其他解决方案不包括我的具体情况:
在我的 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()
吗?