In my model, I want to use a validator to analyze the content of a file, the thing I can not figure out is how to access the content of the file to parse through it as the file has not yet been saved (which is good) when the validators are running.
I'm not understanding how to get the data from the value
passed to the validator into a file (I assume I should use tempfile
) so I can then open it and evaluate the data.
Here's a simplified example, in my real code, I want to open the file and evaluate it with csv.
in 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()])
Thanks for the help!
Take a look how this is done in the ImageField implementation:
So your ValidateFile
class may be something like this:
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
No need for tempfile
:
The value
passed to a FileField
validator is an instance of FieldFile
, as already mentioned by the OP.
Under the hood, the FieldFile
instance might already use a tempfile.NamedTemporaryFile
(source), or it might wrap an in-memory file, but you need not worry about that:
To "evaluate the data" you can simply treat the FieldFile
instance as any Python file object.
For example, you could iterate over it:
def my_filefield_validator(value):
# note that value is a FieldFile instance
for line in value:
... # do something with line
The documentation says:
In addition to the API inherited from
File
such asread()
andwrite()
,FieldFile
includes several methods that can be used to interact with the underlying file: ...
and the FieldFile
class provides
... a wrapper around the result of the
Storage.open()
method, which may be aFile
object, or it may be a custom storage’s implementation of theFile
API.
An example of such an underlying file implementation is the InMemoryUploadedFile
docs/source.
Also from the docs:
The
File
class is a thin wrapper around a Python file object with some Django-specific additions
Also note: class-based validators vs function-based validators
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With