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ビットのバイト文字列を解釈できる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()ますか?

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 に答える