あなたはプロトコルバージョン0を使用してもピクルスデータは、不透明な、バイナリデータである:あなたがTextField
にそれを保存しようとすると
>>> pickle.dumps(data, 0)
'(dp0\nI1\nV\xe9\np1\ns.'
をDjangoはそのデータをUTF8にデコードして保存します。これはUTF-8でエンコードされたデータではないため失敗します。それは、代わりにバイナリデータである:
>>> pickled_data.decode('utf8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/mj/Development/venvs/stackoverflow-2.7/lib/python2.7/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xe9 in position 9: invalid continuation byte
ソリューションはにはTextField
でこれを格納しようではありません。代わりにBinaryField
を使用してください。
生のバイナリデータを格納するフィールド。それはbytes
割り当てをサポートしています。このフィールドは機能に制限があることに注意してください。たとえば、BinaryField値に対してクエリーセットをフィルタリングすることはできません。
あなたは(Pythonの2列は、Python 3にbytes
に改名バイト文字列、です)bytes
値を持っています。
データフィールドにデータを格納することを奨励する場合は、明示的にそれをlatin1
としてデコードします。ラテン1コーデックマップUnicodeのコードポイントに一対一のバイト:
>>> pickled_data.decode('latin1')
u'(dp0\nI1\nV\xe9\np1\ns.'
と再びunpickle化する前に、もう一度エンコードご確認してください。
>>> encoded = pickled_data.decode('latin1')
>>> pickle.loads(encoded)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/mj/Development/Libraries/buildout.python/parts/opt/lib/python2.7/pickle.py", line 1381, in loads
file = StringIO(str)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 9: ordinal not in range(128)
>>> pickle.loads(encoded.encode('latin1'))
{1: u'\xe9'}
この値を許可すればことに注意してください。ブラウザに戻り、テキストフィールドにもう一度戻ると、ブラウザはそのデータ内の文字を置き換えている可能性があります。たとえば、Internet Explorerは\n
文字を\r\n
に置き換えます。これは、テキストを処理しているとみなされるためです。
that is a security hole waiting for exploitationのように、ネットワーク接続からのピクルデータの受け入れを許可するべきではありません。
オプション3:UnicodeデータをUTF-8でエンコードされた文字列として格納します。 –
オプション4:代わりにバイナリ列型を使用します。 –
ピクルデータは*バイナリ*データです。これをUTF-8(テキストエンコーディング)にエンコードすることはできません。 –