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">

Надеюсь, это поможет.

Вернуться на верх