Django загрузить файл в конкретный каталог, который зависит от POST URI - PullRequest
9 голосов
/ 17 февраля 2010

Я хочу сохранить загруженные файлы в определенном каталоге, который зависит от URI запроса POST. Возможно, я бы также хотел переименовать файл в какое-то исправленное (например, имя входного файла), чтобы у меня был простой способ выполнить поиск файловой системы и т. Д., А также избежать возможных проблем безопасности.

Какой способ сделать это в Django?

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

Edit2: я полагаю, можно просто 'mv' файл tmp в новом месте. Это дешевая операция, если в одной файловой системе.

Ответы [ 2 ]

9 голосов
/ 30 апреля 2014

Исправлено olooney пример. Сейчас работает

@csrf_exempt
def upload_video_file(request):
    folder = 'tmp_dir2/' #request.path.replace("/", "_")
    uploaded_filename = request.FILES['file'].name
    BASE_PATH = '/home/'
    # create the folder if it doesn't exist.
    try:
        os.mkdir(os.path.join(BASE_PATH, folder))
    except:
        pass

    # save the uploaded file inside that folder.
    full_filename = os.path.join(BASE_PATH, folder, uploaded_filename)
    fout = open(full_filename, 'wb+')

    file_content = ContentFile( request.FILES['file'].read() )

    try:
        # Iterate through the chunks.
        for chunk in file_content.chunks():
            fout.write(chunk)
        fout.close()
        html = "<html><body>SAVED</body></html>"
        return HttpResponse(html)
    except:
        html = "<html><body>NOT SAVED</body></html>"
        return HttpResponse(html)
4 голосов
/ 17 февраля 2010

Django дает вам полный контроль над тем, где (и если) вы сохраняете файлы.См .: http://docs.djangoproject.com/en/dev/topics/http/file-uploads/

В следующем примере показано, как объединить URL-адрес и имя загруженного файла и записать файл на диск:

def upload(request):
    folder = request.path.replace("/", "_")
    uploaded_filename = request.FILES['file'].name

    # create the folder if it doesn't exist.
    try:
        os.mkdir(os.path.join(BASE_PATH, folder))
    except:
        pass

    # save the uploaded file inside that folder.
    full_filename = os.path.join(BASE_PATH, folder, uploaded_filename)
    fout = open(full_filename, 'wb+')
    # Iterate through the chunks.
    for chunk in fout.chunks():
        fout.write(chunk)
    fout.close()

Редактировать: Как это сделатьс FileUploadHandler?Он прослеживается в коде, и кажется, что вам нужно сделать четыре вещи для перепрофилирования TemporaryFileUploadHandler для сохранения вне FILE_UPLOAD_TEMP_DIR:

  1. extended TemporaryUploadedFile и переопределить init () для передачи через другой каталог в NamedTeoraryFile.Он может использовать попытку mkdir, за исключением прохода, который я показал выше.

  2. extension TemporaryFileUploadHandler и переопределение new_file () для использования вышеуказанного класса.

  3. также расширяют init (), чтобы принять каталог, куда вы хотите поместить папку.

  4. Динамически добавить обработчик запроса, проходя черезкаталог, определенный по URL:

    request.upload_handlers = [ProgressBarUploadHandler (request.path.replace ('/', '_')]

Пока нетривиальноэто все же проще, чем писать обработчик с нуля: в частности, вам не нужно писать ни одной строки буферизированного чтения, подверженного ошибкам. Шаги 3 и 4 необходимы, потому что FileUploadHandlers по умолчанию не передают информацию запроса, я полагаю,поэтому вам придется сообщить это отдельно, если вы хотите каким-либо образом использовать URL.

Я не могу порекомендовать написать для этого собственный FileUploadHandler. Это действительно смешивает уровни ответственности.Кроме того, скорость загрузки файла через Интернет незначительна.И если файл небольшой, Django просто сохранит его в памяти, не записывая его во временный файл.У меня плохое предчувствие, что вы все это заработаете и обнаружите, что вы даже не можете измерить разницу в производительности.

...