Ответ 1
Данные сокета являются непрозрачными двоичными данными, даже если вы используете версию протокола 0:
>>> pickle.dumps(data, 0)
'(dp0\nI1\nV\xe9\np1\ns.'
Когда вы пытаетесь сохранить это в TextField
, 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.
У вас есть значение bytes
(строки Python 2 - это байтовые строки, переименованные в bytes
в Python 3).
Если вы настаиваете на сохранении данных в текстовом поле, явным образом расшифруйте его как latin1
; латинский кодек 1 кодирует байты один на один для кодирования Unicode:
>>> pickled_data.decode('latin1')
u'(dp0\nI1\nV\xe9\np1\ns.'
и убедитесь, что вы снова закодировали его перед повторной загрузкой:
>>> 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
, поскольку предполагает, что он имеет дело с текстом.
Не то, чтобы вы когда-либо позволяли принимать данные о сортировке из сетевого соединения в любом случае, потому что