6

I don't want the file to be saved on my server, I just want the file to be read and printed out in the next page. Right now I have this.

(index.html)
    <form name="fileUpload" method="post">
        <input type="file" />
        <input type="submit" value="Submit" />
    </form>

And I'm trying to do something like this-

def upload_file(request):
    if request.method == "POST":
        upload = request.POST.get('fileUpload').read()
        return render(request, 'directory/return.html', {'output': upload})
    else:
        return render(request, 'directory/index.html')

But obviously that just doesn't work. I want it to work for text files and csv files.

Thank you.

Ravaal
  • 3,233
  • 6
  • 39
  • 66

3 Answers3

14

Firstly, there are some things missing in your form which you will have to add.

To upload files using a form, you’ll need to define the enctype as "multipart/form-data" in the <form> element. Also, the file input element should have the name attribute in it

index.html

<form enctype="multipart/form-data" action="/my/url/" method="post"> # define the enctype
    <input type="file"  name="my_uploaded_file"/> # define a 'name' attribute 
    <input type="submit" value="Submit" />
</form>

Then, in your views, you can access the uploaded file using request.FILES dictionary. As per request.FILES docs:

Each key in FILES is the name from the <input type="file" name="" />. Each value in FILES is an UploadedFile.

You can access the uploaded file using my_uploaded_file key in the request.FILES dictionary.

views.py

def upload_file(request):
    if request.method == "POST":
        my_uploaded_file = request.FILES['my_uploaded_file'].read() # get the uploaded file
        # do something with the file
        # and return the result            
    else:
        return render(request, 'directory/index.html')

Note:

request.FILES will only contain data if the request method was POST and the <form> that posted the request has the attribute enctype="multipart/form-data". Otherwise, request.FILES will be empty.

Ravaal
  • 3,233
  • 6
  • 39
  • 66
Rahul Gupta
  • 46,769
  • 10
  • 112
  • 126
0

First of all you have to change your form:

<form method="post" action="/your/view/url/" enctype="multipart/form-data">
    <input name="testing_file" type="file" />
    <input type="submit" value="Submit" />
</form>

Next you'll get file in:

request.FILES['testing_file']
Sławek Kabik
  • 669
  • 8
  • 13
0

The first answer (Rahul Gupta's) worked perfectly fine for me! But here are some errors I encountered (I'm a newbie but maybe this can help someone)


**(TypeError: upload_file() missing 1 required positional argument: 'request')**

To solve it (and because I'm working with routes), at the very top, I didn't use: def upload_file(request): but:

@app.route("/", methods=["GET", "POST"])
def index():

**AttributeError: 'NoneType' object has no attribute 'FILES'**

To solve it, I realized I actually couldn’t use the request.files function because I forgot to install the requests library (and had some trouble doing so because I had to upgrade my PIP version), but I finally did, and then I had to import the requests module.

Here is the link that guide me through this because there's no way I could explain it better: https://www.pythonforbeginners.com/requests/using-requests-in-python


**AttributeError: 'NoneType' object has no attribute 'FILES'** (Again!!!)

I thought I figured out this error, but it came back! After reading many different websites I realized requests.FILES isn't working, but instead it’s requests.files (no caps!). I'm not sure if this was an update but many people had this problem.

Hope this helped!!! :)

Jean-Francois T.
  • 11,549
  • 7
  • 68
  • 107