使用基于 class 的视图重新打开关闭的 django InMemoryFileUpload
Reopening a closed django InMemoryFileUpload using class based views
我有一个 Django 项目,其中涉及用户通过表单上传 CSV 文件。我在forms clean
方法中解析这个文件,然后在views form_valid
方法中我想再次读取文件数据(为了长期存储的目的)。
我的问题是,在 clean
方法中解析文件后,我无法再对文件对象执行 IO 操作,任何尝试这样做都会引发错误。代码如下:
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
方法中对文件执行 IO 操作,示例如下:
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.
我对此的解释是,读取文件的过程以某种方式触发了它的关闭,尽管我不确定在何处或如何关闭。我想知道的是有什么方法可以防止文件在我读取后关闭,或者在文件关闭后重新打开?
我意识到我可以在同一个方法中执行初始 read/parse 和第二个,这应该可以解决我的问题。然而,那时我开始纠结我的担忧,所以宁愿避免它。
原来问题出在io.TextIOWrapper
的使用上,在清理前通过调用text wrapper的detach
方法解决了。
另一个 SO post 中涵盖了更详细的解释:
我有一个 Django 项目,其中涉及用户通过表单上传 CSV 文件。我在forms clean
方法中解析这个文件,然后在views form_valid
方法中我想再次读取文件数据(为了长期存储的目的)。
我的问题是,在 clean
方法中解析文件后,我无法再对文件对象执行 IO 操作,任何尝试这样做都会引发错误。代码如下:
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
方法中对文件执行 IO 操作,示例如下:
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.
我对此的解释是,读取文件的过程以某种方式触发了它的关闭,尽管我不确定在何处或如何关闭。我想知道的是有什么方法可以防止文件在我读取后关闭,或者在文件关闭后重新打开?
我意识到我可以在同一个方法中执行初始 read/parse 和第二个,这应该可以解决我的问题。然而,那时我开始纠结我的担忧,所以宁愿避免它。
原来问题出在io.TextIOWrapper
的使用上,在清理前通过调用text wrapper的detach
方法解决了。
另一个 SO post 中涵盖了更详细的解释: