Django file storage (1) default storage system, django file storage
Django's default file storage system 'django. core. files. storage. filesystemstore' is a local storage system, determined by the DEFAULT_FILE_STORAGE value in settings.
ClassFileSystemStorage
(Location = None,Base_url = None,File_permissions_mode = None,Directory_permissions_mode = None)
The FileSystemStorage class inherits from the Storage class. location is the absolute path of the Storage file. The default value is the MEDIA_ROOT value in settings, and the default value of base_url is the MEDIA_URL value in settings.
When defining the location parameter, you can ignore the MEDIA_ROOT value to store files:
from django.db import modelsfrom django.core.files.storage import FileSystemStoragefs = FileSystemStorage(location='/media/photos')class Car(models.Model): ... photo = models.ImageField(storage=fs)
In this way, the files are stored in the/media/photos folder.
You can directly use Django's file storage system to store files:
>>> from django.core.files.storage import default_storage>>> from django.core.files.base import ContentFile>>> path = default_storage.save('/path/to/file', ContentFile('new content'))>>> path'/path/to/file'>>> default_storage.size(path)11>>> default_storage.open(path).read()'new content'>>> default_storage.delete(path)>>> default_storage.exists(path)False
You can use the _ save method of the FileSystemStorage class to see how files are stored:
def _save(self, name, content): full_path = self.path(name) # Create any intermediate directories that do not exist. # Note that there is a race between os.path.exists and os.makedirs: # if os.makedirs fails with EEXIST, the directory was created # concurrently, and we can continue normally. Refs #16082. directory = os.path.dirname(full_path) if not os.path.exists(directory): try: if self.directory_permissions_mode is not None: # os.makedirs applies the global umask, so we reset it, # for consistency with file_permissions_mode behavior. old_umask = os.umask(0) try: os.makedirs(directory, self.directory_permissions_mode) finally: os.umask(old_umask) else: os.makedirs(directory) except OSError as e: if e.errno != errno.EEXIST: raise if not os.path.isdir(directory): raise IOError("%s exists and is not a directory." % directory) # There's a potential race condition between get_available_name and # saving the file; it's possible that two threads might return the # same name, at which point all sorts of fun happens. So we need to # try to create the file, but if it already exists we have to go back # to get_available_name() and try again. while True: try: # This file has a file path that we can move. if hasattr(content, 'temporary_file_path'): file_move_safe(content.temporary_file_path(), full_path) # This is a normal uploadedfile that we can stream. else: # This fun binary flag incantation makes os.open throw an # OSError if the file already exists before we open it. flags = (os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, 'O_BINARY', 0)) # The current umask value is masked out by os.open! fd = os.open(full_path, flags, 0o666) _file = None try: locks.lock(fd, locks.LOCK_EX) for chunk in content.chunks(): if _file is None: mode = 'wb' if isinstance(chunk, bytes) else 'wt' _file = os.fdopen(fd, mode) _file.write(chunk) finally: locks.unlock(fd) if _file is not None: _file.close() else: os.close(fd) except OSError as e: if e.errno == errno.EEXIST: # Ooops, the file exists. We need a new file name. name = self.get_available_name(name) full_path = self.path(name) else: raise else: # OK, the file save worked. Break out of the loop. break if self.file_permissions_mode is not None: os.chmod(full_path, self.file_permissions_mode) # Store filenames with forward slashes, even on Windows. return force_text(name.replace('\\', '/'))
You can see in the method, first determine whether the directory stored in the file exists, if not, use OS. mkdirs () to create the directory in sequence.
Determine the permission of the Created directory based on the directory_permissions_mode parameter. The value should be (0777 &~ Umask ).
Then create a file using OS. open (). The flags parameter is (OS. O_WRONLY | OS. O_CREAT | OS. O_EXCL | getattr (OS, 'O _ BINARY ', 0 )),
In this case, if the file already exists, an EEXIST exception is reported. Use the get_available_name () method to re-determine the file name.
The mode is 0o666, and the permission is (0666 &~ Umask ).
Content is a FILE object. If everything is normal, use FILE. chunks () to write the content to the FILE in sequence.
Finally, modify the file creation permission based on the file_permissions_mode parameter.