Milano
Milano

Reputation: 18735

How to access file after upload in Django?

I'm working on a web. User can upload a file. This file is in docx format. After he uploads a file and choose which languages he wants to translate the file to, I want to redirect him to another page, where he can see prices for translations. The prices depends on particular language and number of characters in the docx file.

I can't figure out how to handle the file uploaded. I have a function which get's path to file and returns a number of characters. After uploading file and click on submit, I want to call this function so I can render new page with estimated prices.

I've read that I can call temporary_file_path on request.FILES['file'] but it raises

'InMemoryUploadedFile' object has no attribute 'temporary_file_path'

I want to find out how many characters uploaded file contains and send it in a request to another view - /order-estimation.

VIEW:

def create_order(request):
    LanguageLevelFormSet = formset_factory(LanguageLevelForm, extra=5, max_num=5)
    language_level_formset = LanguageLevelFormSet(request.POST or None)
    job_creation_form = JobCreationForm(request.POST or None, request.FILES or None)

    context = {'job_creation_form': job_creation_form,
               'formset': language_level_formset}

    if request.method == 'POST':
        if job_creation_form.is_valid() and language_level_formset.is_valid():
            cleaned_data_job_creation_form = job_creation_form.cleaned_data
            cleaned_data_language_level_formset = language_level_formset.cleaned_data
            for language_level_form in [d for d in cleaned_data_language_level_formset if d]:
                language = language_level_form['language']
                level = language_level_form['level']

                Job.objects.create(
                        customer=request.user,
                        text_to_translate=cleaned_data_job_creation_form['text_to_translate'],
                        file=cleaned_data_job_creation_form['file'],
                        short_description=cleaned_data_job_creation_form['short_description'],
                        notes=cleaned_data_job_creation_form['notes'],
                        language_from=cleaned_data_job_creation_form['language_from'],
                        language_to=language,
                        level=level,
                )
                path =  request.FILES['file'].temporary_file_path
                utilities.docx_get_characters_number(path) # THIS NOT WORKS

            return HttpResponseRedirect('/order-estimation')
        else:
            return render(request, 'auth/jobs/create-job.html', context=context)

    return render(request, 'auth/jobs/create-job.html', context=context)

Upvotes: 3

Views: 2364

Answers (1)

ohrstrom
ohrstrom

Reputation: 2970

The InMemoryUploadedFile does not provide temporary_file_path. The content lives 'in memory' - as the class name implies.

By default Django uses InMemoryUploadedFile for files up to 2.5MB size, larger files use TemporaryFileUploadHandler. where the later provides the temporary_file_path method in question. Django Documentation

So an easy way would be to change your settings for FILE_UPLOAD_HANDLERS to always use TemporaryFileUploadHandler:

FILE_UPLOAD_HANDLERS = [
    'django.core.files.uploadhandler.TemporaryFileUploadHandler',
]

Just keep in mind that this is not the most efficient way when you have a site with a lot of concurrent small upload requests.

Upvotes: 9

Related Questions