Повторное открытие закрытого django InMemoryFileUpload с помощью представлений на основе классов

У меня есть Django проект, в котором пользователь загружает CSV файл через форму. Я разбираю этот файл в методе forms clean, а затем в методе views form_valid я хочу снова прочитать данные файла (для целей долгосрочного хранения).

Моя проблема заключается в том, что после разбора файла в методе clean я больше не могу выполнять операции ввода-вывода для объекта файла, любая попытка сделать это вызывает ошибку. Код ниже:

class MyForm(forms.Form):
    file = forms.FileField()
    def clean(self):
        cleaned_data = super().clean()
        file = cleaned_data["file"]
        reader = csv.DictReader(io.TextIOWrapper(file))
        for row in reader:
            ...  # process data
        return cleaned_data

class MyView(generic.FormView):
    form_class = MyForm

    def form_valid(self, form):
        file = form.files["file"]
        file.read()  # raises ValueError: I/O operation on closed file.

На этом этапе уже невозможно вызвать другие методы, такие как file.open(), так как это приведет к тому же самому исключению.

Меня смущает то, что в моем приложении есть другие примеры, где операции ввода-вывода могут быть выполнены над файлом в методе form_valid, пример ниже:

class MyOtherForm(forms.Form):
    file = forms.FileField()

class MyOtherView(generic.FormView):
    form_class = MyOtherForm

    def form_valid(self, form):
        file = form.files["file"]
        file.read()  # this works, no error raised.

Моя интерпретация этого заключается в том, что каким-то образом процесс чтения файла вызывает его закрытие, хотя я не уверен, где и как. Я хочу знать, есть ли способ предотвратить закрытие файла после его чтения или открыть его снова после закрытия?

Я понимаю, что могу выполнить и начальное чтение/разбор и второе в одном и том же методе, и это решит мою проблему. Однако на этом этапе я начинаю запутываться в своих проблемах, поэтому предпочел бы избежать этого.

Оказывается, проблема заключалась в использовании io.TextIOWrapper, она была решена вызовом метода detach на текстовой обертке до ее очистки.

Более подробное объяснение дано в другом посте SO: Почему TextIOWrapper закрывает данный поток BytesIO?

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