Вызывайте ошибку валидации в forms.py, когда заголовок/строка пуста или имеет неправильную форму.
Я пытаюсь решить эту проблему в течение некоторого времени и зашел в тупик, эта проблема немного уникальна в том смысле, что файл csv, для которого я проверяю заголовок, находится в файле, загруженном в forms.py. Я имею в виду, что проверяемый csv-файл не существует ни в одном каталоге, поэтому вы не можете просто открыть определенный файл, просто из моего исследования других решений, все они, кажется, о существующем файле в каталоге, а не о загрузке файла.
Итак, заголовок должен быть = "IP Address", и форма отправляется без проблем, когда заголовок файла равен " " или != "IP Address", при отправке формы появляется окно отладки Django. Я борюсь с вводом ошибки валидации или реализацией редиректа.
Если у вас есть какие-либо полезные ссылки, документация или вы хотите решить проблему, пожалуйста, не стесняйтесь, я буду вам очень признателен.
import csv
import io
import pandas as pd
from typing import Any
from django import forms
from django.core.exceptions import ValidationError
from django.core.validators import FileExtensionValidator
from api.utils.network_utils import NetworkUtil
from .models import BlockedList
forms.py
class CSVForm(forms.Form):
csv_file = forms.FileField(required=True, validators=[FileExtensionValidator(allowed_extensions=[".csv", ".xls", "xlsx"])])
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.ips_from_csv = []
def get_ips_from_csv(self):
return self.ips_from_csv
def clean_csv_file(self):
csv_file = self.cleaned_data.get("csv_file")
if not csv_file:
return
with csv_file.open() as file:
reader = csv.DictReader(io.StringIO(file.read().decode("utf-8")))
for row in reader:
form_data = self.cleaned_data.copy()
form_data["address"] = NetworkUtil.extract_ip_address(row["IP Address"])
self.ips_from_csv.append(form_data["address"])
Я знаю, что проверка расширения файла все еще слаба, поскольку она не проверяет содержимое файла, я делаю это самостоятельно. Но вот с чем я столкнулся, так это с clean_csv_file(self), поле файла не существует в моем models.py, поскольку я не храню эти файлы/загрузки в каком-либо каталоге MEDIA.
В конце вашего метода CSVForm.clean_csv_file()
есть такая строка:
form_data["address"] = NetworkUtil.extract_ip_address(row["IP Address"])
Переменная row
имеет тип dict
, где ключами являются заголовки столбцов (то есть ключами являются названия столбцов в CSV-файле, который обычно определяется первой строкой файла).
Если вы обращаетесь к переменной row
по ключу IP Address
, это сработает, только если в первой строке CSV-файла есть слова IP Address
; в противном случае ваша строка кода может вызвать ошибку KeyError: IP Address is not a valid key
.
Для решения этой проблемы можно добавить код, который будет гарантировать, что первая строка файла содержит правильные имена перед итерацией по строкам файла.
Или вы можете добавить в код логику обработки ошибок (например, try-except
).