When using Django's Default Storage should/can you close() an opened file?

Viewed 1415

When using Django's DefaultStorage it's possible to open and read a file something like this:

from django.core.files.storage import default_storage

file = default_storage.open("dir/file.txt", mode="rb")
data = file.read()

When using python's own open() method, it's best to close() the file afterwards, or use a with open("dir/file.txt") as file: construction.

But reading the docs for Django's Storage classes, and browsing the source, I don't see a close() equivalent.

So my questions are:

  1. Should a file opened with Django's Default Storage be closed?
  2. If so, how?
  3. If not, why isn't it necessary?
1 Answers

You don't see a close method because you are looking at the Storage class. The open method of the Storage class returns an instance of django.core.files.base.File [Source code] which basically wraps the python file object and also has a close method that closes the file (The methods like read, etc. are inherited from FileProxyMixin).

Generally when you open a file you should close it, this is the same with Django, which is also emphasised in the documentation:

Closing files is especially important when accessing file fields in a loop over a large number of objects. If files are not manually closed after accessing them, the risk of running out of file descriptors may arise. This may lead to the following error:

OSError: [Errno 24] Too many open files

But there are few instances where you shouldn't close files, which mostly are when you are passing the file to some function / method / object that will read it, for example if you create a FileResponse object you shouldn't close the file as Django will close it by itself:

The file will be closed automatically, so don’t open it with a context manager.

To complete your example code, you will close the file as:

from django.core.files.storage import default_storage

file = default_storage.open("dir/file.txt", mode="rb")
data = file.read()
file.close()
Related