I am building a very simple application which includes one page where a user submits a list of zip codes and then is returned a file with zip codes in a certain radius of the original list.
My problem is that my function for processing the file that is contained in the views.py file is not able to retrieve the ‘.csv’ file after the post form. The FILES metadata on the request is missing and I cannot figure out why. More details below:
Error I am seeing:
Internal Server Error: /zip_app/
Traceback (most recent call last):
File "/home/louis/.cache/pypoetry/virtualenvs/zip-radius-app-1xSGHScf-py3.10/lib/python3.10/site-packages/django/utils/datastructures.py", line 84, in __getitem__
list_ = super().__getitem__(key)
KeyError: 'csvFile'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/louis/.cache/pypoetry/virtualenvs/zip-radius-app-1xSGHScf-py3.10/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
File "/home/louis/.cache/pypoetry/virtualenvs/zip-radius-app-1xSGHScf-py3.10/lib/python3.10/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/louis/.cache/pypoetry/virtualenvs/zip-radius-app-1xSGHScf-py3.10/lib/python3.10/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper
return view_func(request, *args, **kwargs)
File "/home/louis/Documents/github/zip_radius_tool/zip_radius_app/zip_app/views.py", line 30, in index
f = request.FILES['csvFile']
File "/home/louis/.cache/pypoetry/virtualenvs/zip-radius-app-1xSGHScf-py3.10/lib/python3.10/site-packages/django/utils/datastructures.py", line 86, in __getitem__
raise MultiValueDictKeyError(key)
django.utils.datastructures.MultiValueDictKeyError: 'csvFile'
HTML for the index page where the user submits the .csv file:
<!DOCTYPE html>
<html lang="en">
<head>
<title>W3.CSS Template</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
body {font-family: "Lato", sans-serif}
.mySlides {display: none}
</style>
</head>
<body>
<!-- Page content -->
<div class="w3-content" style="max-width:2000px;margin-top:46px">
<!-- The Band Section -->
<div class="w3-container w3-content w3-center w3-padding-64" style="max-width:800px" id="band">
<form action="" method="post">
<input type="file" name="csvFile" accept=".csv" enctype="multipart/form-data">
<button type="submit" formmethod="post">Submit using POST</button>
</form>
</div>
<!-- End Page Content -->
</div>
</body>
</html>
And my views.py file (the ‘index’ function is getting properly called but is failing on ‘f.request.FILES[‘csvFile’]’):
from django.shortcuts import render
from uszipcode import SearchEngine
import pandas as pd
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
# Create your views here.
def index(request):
context = {}
if request.method == 'POST':
d = request.POST
print(d)
f = request.FILES['csvFile']
print(type(f))
radius_results = pull_radius_zips(f)
print('checking this works to this point')
return render(request, "zip_app/index.html", context)
At first I thought i might be an issue with redirecting to the same view on submission of the form but I found this is actually a standard thing to do. Moreover, the index view properly catches when the submission is POST.
I am also seeing that the request.POST properly populates with the name of my test file (‘zip_codes.csv’) as the value and under the variable ‘csvFile’, so somewhere the csv file is being dropped from the request object.
Additional info: I have the csrf token check disabled for this view.
2
Answers
You forgot to use
enctype="multipart/form-data
in your form. You placed it wrong inside the input.This is why your form is not processing the file in request. This should solve the issue.
i think you’re using the incorrect attribute to retrieve the csv file
instead of :
use :
additionally, make sure that you have set the ‘enctype’ attribute in tour html correctly as mentioned in the answer above:
Hope this helps.