如何预处理保存在 Django 中的文件内容?



在Django 2.2中有一个.csv被保存到一个FileField

在保存之前,我想删除其中的一些行。

这是我目前为止写的:

# A Custom File Field that will modify the file contents before saving it
class CustomFileField(models.FileField):
# The method that gets called before the save happens
def pre_save(self, model_instance, add):
file_field = super().pre_save(model_instance, add)
file_field = self.update_file_contents(file_field)
return file_field
def update_file_contents(self, file_field):
# NEED TO SOMEHOW UPDATE THE CONTENTS OF
# THE file_field HERE BEFORE RETURNING IT
return file_field
# The model that uses this Custom File Field
class MyModel(models.Model):
my_csv_file = CustomFileField(upload_to='results/%Y/%m/%d/')

我不太确定我的update_file_contents方法需要做什么来更新文件的内容。在调用我的方法时,文件是否已保存到文件系统中?还是还在记忆里?

或者我应该忘记定制FileField,并简单地覆盖我的MyModelsave方法,以便在文件保存到文件系统后,我再次打开它,并像修改任何文件一样修改它?

查看父类(models.FileField),我能够编写以下代码,据我所知,它做了我想要的:

# A Custom File Field that will modify the file contents before saving it
class CustomFileField(models.FileField):
# The method that gets called before the save happens
def pre_save(self, model_instance, add):
file = models.Field.pre_save(self, model_instance, add)
if file and not file._committed:
self.modify_content(file, model_instance)
file.save(file.name, file.file, save=False)
return file_field
def update_file_contents(self, file, model_instance):
# Create a temporary backup of file contents in memory
contents = file.read().decode("utf-8")
# Delete the file contents from memory
file.seek(0)
file.truncate()
# Re-add the file contents, line by line, if the line passes validation
for line in contents.splitlines():
if self._line_passes_validation(line, model_instance):
file.write(line.encode("utf-8"), + b"n")
def _line_passes_validation(self, line, model_instance):
"""
Looks at line (str), and decides if it passes validation.
Returns True if it does, or False if it doesn't.
model_instance can be used to check related fields in the database, which can help in the decision
"""
...
# The model that uses this Custom File Field
class MyModel(models.Model):
my_csv_file = CustomFileField(upload_to='results/%Y/%m/%d/')

据我所知,当文件上传时,它被完整地存储在RAM中。在这里,在file.save(...)将其保存到磁盘之前,我通过备份该文件的内容来修改要保存的文件的内容,只有当每行通过验证时才重新添加它。

这样做有什么问题吗?

最新更新