#python
#python
Вопрос:
Я пытаюсь хэшировать имя файла, а затем сохранить в БД. Я использую Flask и Python 3.4
Это код для загрузки:
@app.route('/', methods=['GET', 'POST'])
def upload_pic():
if request.method == 'POST':
file = request.files['file']
try:
extension = file.filename.rsplit('.', 1)[1].lower()
except IndexError as e:
abort(404)
if file and check_extension(extension):
# Salt and hash the file contents
filename = md5(file.read() str(round(time.time() * 1000))).hexdigest() '.' extension
file.seek(0) # Move cursor back to beginning so we can write to disk
file.save(os.path.join(app.config['UPLOAD_DIR'], filename))
add_pic(filename)
gen_thumbnail(filename)
return redirect(url_for('show_pic', filename=filename))
else: # Bad file extension
abort(404)
else:
return render_template('upload.html')
Когда я отправляю форму, я получаю обратную трассировку ошибки.
Traceback (most recent call last):
File "C:Python34libsite-packagesflaskapp.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "C:Python34libsite-packagesflaskapp.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "C:Python34libsite-packagesflaskapp.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:Python34libsite-packagesflask_compat.py", line 33, in reraise
raise value
File "C:Python34libsite-packagesflaskapp.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "C:Python34libsite-packagesflaskapp.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:Python34libsite-packagesflaskapp.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:Python34libsite-packagesflask_compat.py", line 33, in reraise
raise value
File "C:Python34libsite-packagesflaskapp.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "C:Python34libsite-packagesflaskapp.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:UsersAjayPycharmProjectscodehackr-uploadflaskgur.py", line 70, in upload_pic
filename = md5(file.read() (round(time.time() * 1000))).hexdigest() '.' extension
TypeError: can't concat bytes to int
Я не знаю, что происходит не так, пожалуйста, просветите меня.
Спасибо.
Комментарии:
1. Ваша трассировка не соответствует коду. Код уже исправлен, но трассировка показывает, что вы используете другой код.
Ответ №1:
Вы пытаетесь объединить результат file.read()
с результатом round(time.time() * 1000))
, который является целым числом. Вот почему вы получаете ошибку:
TypeError: can't concat bytes to int
Попробуйте привести целое число:
file.read() bytes(round(time.time() * 1000)))
Но, как заметил @Lev Levitsky, похоже, что в вашем коде уже есть исправление: вы уверены, что запускаете последнюю версию своего кода?
Комментарии:
1. Не было бы более уместным преобразовать его в
bytes
type?2. Ты прав! Не знаю, почему я допустил эту ошибку 🙂
Ответ №2:
Да, как писал julienc, проблема заключалась в попытке объединить результат file.read()
, типа bytes
, с результатом round(time.time() * 1000))
, который был an int
.
НО НЕ ДЕЛАЙТЕ ТОГО, ЧТО ПОКАЗАНО В ДРУГОМ ОТВЕТЕ! Сохраняйте спокойствие и продолжайте читать…
Как создать байты в Python 3
# (1)
bytes(12) == b'x00x00x00x00x00x00x00x00x00x00x00x00'
# (2)
bytes([12]) == b'x0c'
bytes([444]) -> ValueError("bytes must be in range(0, 256)")
bytes([0x01, 0xBC]) == b'x01xbc'
# (3)
( 12).to_bytes(8, 'big') == b'x00x00x00x00x00x00x00x0c'
(444).to_bytes(8, 'big') == b'x00x00x00x00x00x00x01xbc'
# (4)
str(12).encode('utf8') == b'12'
(1) Создать bytes
длину n
, которая пуста (заполнена нулями)
Это редко то, что вы хотите. Осторожно!
В контексте этого вопроса md5(file.read() str(round(time.time() * 1000)))
хэшируется содержимое файла, а затем около 1,5 триллионов пустых байтов. Технически он все еще делает то, что нужно, но тьфу, за какие вычислительные затраты 🙂
(2) Создать bytes
длину, n
содержащую указанные значения
Каждое исходное значение должно быть от 0 до 255, чтобы поместиться в байт.
Конечно, можно было бы также записать с помощью кортежа, но это немного уродливее для случая длины 1: bytes((12,))
(3) Создать bytes
как собственное / двоичное представление целого числа
Это ответ на исходный вопрос, как преобразовать целое число в поток и т. Д.
Но теперь вам нужно подумать о некоторых низкоуровневых вещах, таких как количество байтов вывода и порядковый номер (порядок байтов). Подробности см. в int.to_bytes()
документах.
Конечно, дополнительные круглые скобки необходимы только для буквального значения 12
в этом примере. Они могут быть опущены при использовании переменной или другого выражения.
(4) Создайте байты из указанного текста ( str
).
В качестве альтернативы вышесказанному, иногда вам не нужно или не хочется думать о низкоуровневых соображениях, и тогда та же цель может быть достигнута простым хешированием (или чем угодно) простого текстового представления значения человеком.
Конечно, 'ascii'
или что-то еще можно было бы использовать вместо 'utf8'
этого в этом примере. Но почему бы не тренировать мышечную память с помощью того, что вы хотите почти повсеместно в любом другом месте?