let me put it like this:
model.py:
class Task(models.Model):
...
seq_file = models.FileField(upload_to=\'files/\', blank=True, null=True)
...
because open method of models.FileField doesn't return anything
you can just use:
task.seq_file.read()
and you don't need calculate path of file for checking if file exist. you can use task.seq_file.path:
if not os.path.isfile(task.seq_file.path):
....
When in doubt, check the code. Here's an excerpt from django.db.models.fields.files
:
def open(self, mode='rb'):
self._require_file()
self.file.open(mode)
# open() doesn't alter the file's contents, but it does reset the pointer
open.alters_data = True
So, in the case of a FileField
, open
reopens the file using the specified mode. Then, once you call open
, you can continue to use methods like read
using the newly applied mode.
A FileField will give you a file-like object and there is no need to call open() on it. In your example, just call task.seq_file.file
.
Why is that? There are many storage backends for FileField
, and many of them are not backed by a file in disk (think of S3 storage, for example). I guess that is why the documentation says it returns a file-like object, not a file. For some kinds of storage the "open" method makes no sense.
Surprisingly but django.db.models.fields.files
does not utilize file.storage.exists()
method so I had to implement my own small function to have cross-storage compatible check for actual physical file existence:
# Check whether actual file of FileField exists (is not deleted / moved out).
def file_exists(obj):
return obj.storage.exists(obj.name)