Вызывайте ошибку валидации в 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).

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