如何在 FileField 内容上使用验证器

How to use validators on FileField content

在我的模型中,我想使用验证器来分析文件的内容,我不知道如何访问文件的内容来解析它,因为文件还没有被解析当验证器为 运行.

时保存(这很好)

我不明白如何从传递给验证器的 value 中获取数据到一个文件中(我假设我应该使用 tempfile)所以我可以打开它并评估数据.

这是一个简化的例子,在我的真实代码中,我想打开文件并用 csv 对其进行评估。

在Models.py

class ValidateFile(object):
    ....
    def __call__(self, value):
        # value is the fieldfile object but its not saved
        # I believe I need to do something like:
        temp_file = tempfile.TemporaryFile()
        temp_file.write(value.read())
        # Check the data in temp_file
    ....

class MyItems(models.Model):
    data = models.FileField(upload_to=get_upload_path,
                            validators=[FileExtensionValidator(allowed_extensions=['cv']),
                            ValidateFile()])

感谢您的帮助!

看看在 ImageField 实现中是如何完成的:

所以你的 ValidateFile class 可能是这样的:

from io import BytesIO

class ValidateFile(object):

    def __call__(self, value):
        if value is None:
            #do something when None
            return None

        if hasattr(value, 'temporary_file_path'):
            file = value.temporary_file_path()
        else:
            if hasattr(value, 'read'):
                file = BytesIO(value.read())
            else:
                file = BytesIO(value['content'])

        #Now validate your file

不需要tempfile:

传递给 FileField 验证器的 valueFieldFile 的一个实例,正如 OP 已经提到的那样。

在后台,FieldFile 实例可能已经使用了 tempfile.NamedTemporaryFilesource), or it might wrap an in-memory file,但您不必担心:

要“评估数据”,您可以简单地将 FieldFile 实例视为任何 Python file object.

例如,您可以对其进行迭代:

def my_filefield_validator(value):
    # note that value is a FieldFile instance
    for line in value:
        ... # do something with line

documentation 说:

In addition to the API inherited from File such as read() and write(), FieldFile includes several methods that can be used to interact with the underlying file: ...

并且 FieldFile class 提供

... a wrapper around the result of the Storage.open() method, which may be a File object, or it may be a custom storage’s implementation of the File API.

这种底层文件实现的一个例子是 InMemoryUploadedFile docs/source.

也来自docs

The File class is a thin wrapper around a Python file object with some Django-specific additions

另请注意:class-based validators vs function-based validators