| 5 | class StorageBackendAgnosticFileField(FileField): |
| 6 | """ |
| 7 | Subclass of Django's `FileField` that allows for storage backends to optionally implement a function |
| 8 | `generate_filename` through which they can generate filenames in a manner suitable for their storage mechanisms, |
| 9 | rather than through Django's implementation which is hardwired to specific file systems. |
| 10 | """ |
| 11 | |
| 12 | def parse_upload_to(self): |
| 13 | """ |
| 14 | Same as `FileField.get_directory_name`, but without the file system specifics. Allows for date formatting. |
| 15 | |
| 16 | Returns |
| 17 | ------- |
| 18 | str |
| 19 | The parsed `upload_to` string. |
| 20 | """ |
| 21 | return force_text(datetime.datetime.now().strftime(force_str(self.upload_to))) |
| 22 | |
6 | | # allow for customized filename generation |
7 | | if hasattr(self.storage, 'generate_filename'): |
| 24 | """ |
| 25 | Overrides the regular implementation by first checking of the storage backend doesn't already implement this |
| 26 | logic. Otherwise, falls back to the traditional implementation. |
| 27 | |
| 28 | Parameters |
| 29 | ---------- |
| 30 | instance : object |
| 31 | The model instance the current file is attached to. It's passed to the `upload_to` call when `upload_to` is |
| 32 | callable. |
| 33 | filename : str |
| 34 | The filename, if any. |
| 35 | |
| 36 | Returns |
| 37 | ------- |
| 38 | str |
| 39 | The newly generated and/or validated filename. |
| 40 | """ |
| 41 | if hasattr(self.storage, 'generate_filename') and callable(self.storage.generate_filename): |
11 | | |
12 | | filename = force_text(datetime.datetime.now().strftime(force_str(self.upload_to))) |
13 | | return self.storage.generate_filename(filename) |
14 | | |
15 | | # If upload_to is a callable, make sure that the path it returns is |
16 | | # passed through get_valid_name() of the underlying storage. |
17 | | if callable(self.upload_to): |
18 | | directory_name, filename = os.path.split(self.upload_to(instance, filename)) |
19 | | filename = self.storage.get_valid_name(filename) |
20 | | return os.path.normpath(os.path.join(directory_name, filename)) |