CSV-файл не передается при отправке html-формы методом POST (в контексте использования Django)
Я создаю очень простое приложение, которое включает одну страницу, где пользователь отправляет список почтовых индексов, а затем ему возвращается файл с почтовыми индексами в определенном радиусе от исходного списка.
Моя проблема заключается в том, что моя функция обработки файла, содержащаяся в файле views.py, не может получить файл '.csv' после формы post. Метаданные FILES в запросе отсутствуют, и я не могу понять, почему. Подробности ниже:
Ошибка, которую я вижу:
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 для индексной страницы, на которой пользователь отправляет файл .csv:
<!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>
И мой файл views.py (функция 'index' вызывается правильно, но не срабатывает на '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)
Сначала я подумал, что может быть проблема с перенаправлением на одно и то же представление при отправке формы, но оказалось, что это стандартная вещь, которую нужно делать. Более того, представление index правильно перехватывает, когда отправка формы происходит по POST.
Я также вижу, что request.POST правильно заполняется именем моего тестового файла ('zip_codes.csv') в качестве значения и в переменной 'csvFile', так что где-то файл csv отбрасывается из объекта запроса.
Дополнительная информация: У меня отключена проверка токена csrf для этого представления.
Вы забыли использовать enctype="multipart/form-data
в своей форме. Вы неправильно разместили его внутри ввода.
<form action="" method="post" enctype="multipart/form-data">
..........
</form>
Поэтому ваша форма не обрабатывает файл в запросе. Это должно решить проблему.
я думаю, что вы используете неправильный атрибут для получения файла csv вместо :
f = request.FILES['csvFile']
использовать :
f = request.FILES.get['csvFile']
дополнительно, убедитесь, что вы правильно установили атрибут 'enctype' в туре html, как указано в ответе выше:
<form action="" method="post" enctype="multipart/form-data">
Надеюсь, это поможет.