まず第一に、私はこのような多くの同様の質問があることを知っていますが、他の解決策は私の特定のケースをカバーしていません:
私の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ビットのバイト文字列を解釈できるtext_factory(text_factory = strなど)を使用しない限り、8ビットのバイト文字列を使用しないでください。代わりに、アプリケーションを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()がキーワード引数'connection'に対して複数の値を取得しました
私はこれと一緒に暮らすことができましたが、それを除外することの意味を完全には理解していません。を呼び出さなくても機能しsuper()
ますか?