diff --git a/django/core/files/base.py b/django/core/files/base.py index 85b3c21cba..159a98e52f 100644 --- a/django/core/files/base.py +++ b/django/core/files/base.py @@ -36,19 +36,26 @@ class File(FileProxyMixin): def __len__(self): return self.size + def _get_size_from_underlying_file(self): + if hasattr(self.file, 'size'): + return self.file.size + if hasattr(self.file, 'name'): + try: + return os.path.getsize(self.file.name) + except (OSError, TypeError): + pass + if hasattr(self.file, 'tell') and hasattr(self.file, 'seek'): + pos = self.file.tell() + self.file.seek(0, os.SEEK_END) + size = self.file.tell() + self.file.seek(pos) + return size + raise AttributeError("Unable to determine the file's size.") + def _get_size(self): - if not hasattr(self, '_size'): - if hasattr(self.file, 'size'): - self._size = self.file.size - elif hasattr(self.file, 'name') and self.file.name is not None and os.path.exists(self.file.name): - self._size = os.path.getsize(self.file.name) - elif hasattr(self.file, 'tell') and hasattr(self.file, 'seek'): - pos = self.file.tell() - self.file.seek(0, os.SEEK_END) - self._size = self.file.tell() - self.file.seek(pos) - else: - raise AttributeError("Unable to determine the file's size.") + if hasattr(self, '_size'): + return self._size + self._size = self._get_size_from_underlying_file() return self._size def _set_size(self, size):