Суффикс Python mkstemp

У меня есть следующий фрагмент кода, который обрабатывает загрузку изображений для меня в проекте Django, над которым я работаю:

def upload_handler(source):
    fd, filepath = tempfile.mkstemp(prefix=source.name, dir=MEDIA_ROOT)
    with open(filepath, 'wb') as dest:
        shutil.copyfileobj(source, dest)
        return MEDIA_URL + basename(dest.name)

Все нормально работает с частью загрузки, но mkstemp сохраняет мое изображение с дополнительными 6 случайными суффиксами после расширения (например, test.png -> test.pngbFVeyh). Даже если я передам суффикс во второй строке кода, он добавляет его, но также и дополнительные 6 случайных символов. Другая странная вещь в том, что в папке загрузки (в моем случае MEDIA_ROOT) она создается вместе с другим пустым файлом с типом документа в формате обычного текста с тем же именем, что и изображение (например, test.pngbFVeyh). Я прочитал документацию по mkstemp, но не нашел альтернативного решения.

2 ответа

Решение

Имя генерируется случайным образом, потому что это цель tempfile.mkstemp, Файл с таким именем создан, потому что это как tempfile.mkstemp работает. Он также открывается и дескриптор файла возвращается вам в fd которую ты игнорируешь. Вы, кажется, не понимаете, как tempfile.mkstemp следует использовать, и вам, вероятно, нужно использовать что-то другое вместо этого.

def upload_handler(source):
    # this is creating a temp file and returning an os handle and name
    fd, filepath = tempfile.mkstemp(prefix=source.name, dir=MEDIA_ROOT)
    # this next line just clears the file you just made (which is already empty)
    with open(filepath, 'wb') as dest: 
        # this is a strange way to get a fobj to copy :)
        shutil.copyfileobj(source, dest)
        return MEDIA_URL + basename(dest.name)

префикс и суффикс делают именно это, поэтому, если вы не хотите, чтобы ваше имя файла начиналось или заканчивалось временными символами, вам нужно использовать как префикс, так и суффикс. Например,

name = os.path.basename(source.name)
prefix, suffix = os.path.splitext(name)
_, filepath = tempfile.mkstemp(prefix=prefix, suffix=suffix, dir=MEDIA_ROOT)

но было бы лучше, если вы используете tempfile.NamedTemporaryFile, а затем возвращается файлоподобный объект (поэтому вам не нужно создавать fobj из имени файла, а временный файл удаляется по умолчанию, когда закончите).

fobj, _ = tempfile.NamedTemporaryFile(prefix=prefix, suffix=suffix, dir=MEDIA_ROOT)
shutil.copyfileobj(source, fobj)
Другие вопросы по тегам