Support for many storage backends in Django
.. image:: https://raw.githubusercontent.com/jschneier/django-storages/master/docs/logos/horizontal.png :alt: Django-Storages :width: 100%
.. image:: https://img.shields.io/pypi/v/django-storages.svg :target: https://pypi.org/project/django-storages/ :alt: PyPI Version
.. image:: https://github.com/jschneier/django-storages/actions/workflows/ci.yml/badge.svg :target: https://github.com/jschneier/django-storages/actions/workflows/ci.yml :alt: Build Status
Installing from PyPI is as easy as doing:
.. code-block:: bash
pip install django-storages
If you'd prefer to install from source (maybe there is a bugfix in master that hasn't been released yet) then the magic incantation you are looking for is:
.. code-block:: bash
pip install -e 'git+https://github.com/jschneier/django-storages.git#egg=django-storages'
For detailed instructions on how to configure the backend of your choice please consult the documentation.
django-storages is a project to provide a variety of storage backends in a single library.
This library is usually compatible with the currently supported versions of Django. Check the Trove classifiers in setup.py to be sure.
django-storages is backed in part by Tidelift_. Check them out for all of your enterprise open source
software commercial support needs.
.. _Tidelift: https://tidelift.com/subscription/pkg/pypi-django-storages?utm_source=pypi-django-storages&utm_medium=referral&utm_campaign=enterprise&utm_term=repo
To report a security vulnerability, please use the Tidelift security contact_. Tidelift will coordinate the
fix and disclosure. Please do not post a public issue on the tracker.
.. _Tidelift security contact: https://tidelift.com/security
Issues are tracked via GitHub issues at the project issue page <https://github.com/jschneier/django-storages/issues>_.
Documentation for django-storages is located at https://django-storages.readthedocs.io/.
#. Check for open issues <https://github.com/jschneier/django-storages/issues>_ at the project
issue page or open a new issue to start a discussion about a feature or bug.
#. Fork the django-storages repository on GitHub <https://github.com/jschneier/django-storages>_ to start making changes.
#. Add a test case to show that the bug is fixed or the feature is implemented
correctly.
#. Bug me until I can merge your pull request.
Please don't update the library version in CHANGELOG.rst or storages/__init__.py, the maintainer will do that on release.
If you're the first to update the CHANGELOG in this release cycle, just put the version as XXXX-XX-XX.
This repo began as a fork of the original library under the package name of django-storages-redux and became the official successor (releasing under django-storages on PyPI) in February of 2016.
1.14.2 (2023-10-08)
S3File (#1321_)ImproperlyConfigured when no bucket_name is set (#1322_).. _#1321: https://github.com/jschneier/django-storages/pull/1321 .. _#1322: https://github.com/jschneier/django-storages/pull/1322
1.14.1 (2023-09-29)
AccountName and AccountKey in connection_string (#1312_)#1303_)S3File.write (#1304_)FileNotFoundError when attempting to read the size of a non-existent file (#1309_)#1302_)ImproperlyConfigured if no bucket_name is set (#1313_)S3File.closed (#1311_).. _#1303: https://github.com/jschneier/django-storages/pull/1303 .. _#1304: https://github.com/jschneier/django-storages/pull/1304 .. _#1309: https://github.com/jschneier/django-storages/pull/1309 .. _#1302: https://github.com/jschneier/django-storages/pull/1302 .. _#1313: https://github.com/jschneier/django-storages/pull/1313 .. _#1312: https://github.com/jschneier/django-storages/pull/1312 .. _#1311: https://github.com/jschneier/django-storages/pull/1311
1.14 (2023-09-04)
#1235_)(modified|created|accessed)_time methods have been
removed from the various storages, please replace with the get_(modified|created|accessed)_time methodspathlib.PurePath names (#1278_)#1236_)account_(name|key) from connection_string if not provided (#1225_)DropboxStorage.location has been deprecated, please rename to DropboxStorage.root_path, a future version will
remove support for the old name. (#1251_)DropboxStorage has now replaced
DropBoxStorage. Aliases have been added so no change is necessary at this time. A future version might deprecate the old names. (#1250_)DropboxStorage now conforms to the BaseStorage interface (#1251_)#1279_)BASE_URL if it is defined (#1238_)GS_CACHE_CONTROL has been removed. Please set the cache_control parameter of
GS_OBJECT_PARAMETERS instead. (#1220_)FileNotFoundError (#1191_)#1253_)AWS_S3_USE_THREADS has been deprecated in favor of AWS_S3_TRANSFER_CONFIG (#1280_)S3Boto3 to S3. There are no current plans
to deprecate and remove the old namespace but please update if you can. All paths, imports, and classes that previously
referred to s3boto are now s3. E.g S3Boto3Storage has been changed to S3Storage and S3Boto3StorageFile
has been changed to S3File. (#1289). Additionally the install extra is now s3 (#1284)transfer_config/AWS_S3_TRANSFER_CONFIG to customize any of the TransferConfig properties (#1280_)security_token to constructor (#1246_)ContentType from get_object_parameters (#1281_)cloudfront_key_id and cloudfront_key via Django 4.2's OPTIONS (#1274_)S3File.closed (#1249_)S3File (#1282_)S3File not respecting mode on readlines (#1000_)#911_)#1286_).. _#1280: https://github.com/jschneier/django-storages/pull/1280 .. _#1289: https://github.com/jschneier/django-storages/pull/1289 .. _#1284: https://github.com/jschneier/django-storages/pull/1284 .. _#1274: https://github.com/jschneier/django-storages/pull/1274 .. _#1281: https://github.com/jschneier/django-storages/pull/1281 .. _#1282: https://github.com/jschneier/django-storages/pull/1282 .. _#1279: https://github.com/jschneier/django-storages/pull/1279 .. _#1278: https://github.com/jschneier/django-storages/pull/1278 .. _#1235: https://github.com/jschneier/django-storages/pull/1235 .. _#1236: https://github.com/jschneier/django-storages/pull/1236 .. _#1225: https://github.com/jschneier/django-storages/pull/1225 .. _#1251: https://github.com/jschneier/django-storages/pull/1251 .. _#1250: https://github.com/jschneier/django-storages/pull/1250 .. _#1238: https://github.com/jschneier/django-storages/pull/1238 .. _#1220: https://github.com/jschneier/django-storages/pull/1220 .. _#1191: https://github.com/jschneier/django-storages/pull/1191 .. _#1253: https://github.com/jschneier/django-storages/pull/1253 .. _#1246: https://github.com/jschneier/django-storages/pull/1246 .. _#1249: https://github.com/jschneier/django-storages/pull/1249 .. _#1000: https://github.com/jschneier/django-storages/pull/1000 .. _#911: https://github.com/jschneier/django-storages/pull/911 .. _#1286: https://github.com/jschneier/django-storages/pull/1286
1.13.2 (2022-12-23)
#1196_)pathlib.Path names (#1200_)delete() (#1201_)AZURE_CUSTOM_DOMAIN for retrieving blob URLs and storage URL for other operations (#1176_)DEFAULT_RETRY for all upload & delete operations (#1156_)#1203_)#1193_)#1194_).. _#1196: https://github.com/jschneier/django-storages/pull/1196 .. _#1200: https://github.com/jschneier/django-storages/pull/1200 .. _#1201: https://github.com/jschneier/django-storages/pull/1201 .. _#1176: https://github.com/jschneier/django-storages/pull/1176 .. _#1156: https://github.com/jschneier/django-storages/pull/1156 .. _#1203: https://github.com/jschneier/django-storages/pull/1203 .. _#1193: https://github.com/jschneier/django-storages/pull/1193 .. _#1194: https://github.com/jschneier/django-storages/pull/1194
1.13.1 (2022-08-06)
#1168_)DropBoxStorage constructor parameter order to be backwards compatible (#1167_).. _#1167: https://github.com/jschneier/django-storages/pull/1167 .. _#1168: https://github.com/jschneier/django-storages/pull/1168
1.13 (2022-08-05)
#1093_)#1093_)#1093_)AWS_S3_URL_PROTOCOL from http: to https: and remove the
undocumented AWS_S3_SECURE_URLS setting. You should only need to update your settings if you had updated either of
these previously undocumented settings. The default behavior of constructing an https: URL with a custom domain
is unchanged (#1164_)AWS_S3_USE_THREADS to disable threading for compatibility with gevent (#1112_)#1159_)ApiError exception in url() (#1158_)AZURE_ENDPOINT_SUFFIX (#1118_)download_to_stream with readinto (#1113_)AZURE_API_VERSION setting (#1132_)get_modified_time() (#1134_)GS_IS_GZIPPED and GZIP_CONTENT_TYPES (#980_)GS_BLOB_CHUNK_SIZE with files that already exist (#1154_).. _#980: https://github.com/jschneier/django-storages/pull/980 .. _#1118: https://github.com/jschneier/django-storages/pull/1118 .. _#1113: https://github.com/jschneier/django-storages/pull/1113 .. _#1112: https://github.com/jschneier/django-storages/pull/1112 .. _#1132: https://github.com/jschneier/django-storages/pull/1132 .. _#1134: https://github.com/jschneier/django-storages/pull/1134 .. _#1159: https://github.com/jschneier/django-storages/pull/1159 .. _#1158: https://github.com/jschneier/django-storages/pull/1158 .. _#1164: https://github.com/jschneier/django-storages/pull/1164 .. _#1093: https://github.com/jschneier/django-storages/pull/1093 .. _#1154: https://github.com/jschneier/django-storages/pull/1154
1.12.3 (2021-10-29)
#1078_).exists() (#1084, #1085)AZURE_CUSTOM_DOMAIN with an account key credential (#1082, #1083)FileNotFoundError instead of OSerror in .exists() to prevent swallowing socket.timeout exceptions (#1064, #1087).. _#1078: https://github.com/jschneier/django-storages/pull/1078 .. _#1084: https://github.com/jschneier/django-storages/issues/1084 .. _#1085: https://github.com/jschneier/django-storages/pull/1085 .. _#1082: https://github.com/jschneier/django-storages/issues/1082 .. _#1083: https://github.com/jschneier/django-storages/pull/1083 .. _#1064: https://github.com/jschneier/django-storages/issues/1064 .. _#1087: https://github.com/jschneier/django-storages/pull/1087
1.12.2 (2021-10-16)
parameters kwarg to AzureStorage.url to configure blob properties in the SAS token (#1071_)AZURE_CUSTOM_DOMAIN was interpreted as a replacement of blob.core.windows.net rather than as a full domain
(#1073, #1076).. _#1071: https://github.com/jschneier/django-storages/pull/1071 .. _#1073: https://github.com/jschneier/django-storages/issues/1073 .. _#1076: https://github.com/jschneier/django-storages/pull/1076
1.12.1 (2021-10-11)
#1061_)S3ManifestStaticStorage (#1068, #1069).. _#1061: https://github.com/jschneier/django-storages/pull/1061 .. _#1068: https://github.com/jschneier/django-storages/issues/1068 .. _#1069: https://github.com/jschneier/django-storages/pull/1069
1.12 (2021-10-06)
#1046, #1042, #1005_)#1051_)#1003_)#1041_)#1054_)fbe9538_)#1026_)listdir (66f4f8e_)seekable (#860, #1057)True for .exists() if a non-404 error is encountered (#938_)azure-storage-blob, which now has a minimum required version of 12.0. The settings AZURE_EMULATED_MODE, AZURE_ENDPOINT_SUFFIX, and AZURE_CUSTOM_CONNECTION_STRING are now ignored. (#784, #805)#1063_)google-cloud-storage is now 1.27.0 (#994_)#994_)GS_CACHE_CONTROL will be removed in 1.13. Please set the cache_control parameter of GS_OBJECT_PARAMETERS instead. (#970_)GS_OBJECT_PARAMETERS and overridable GoogleCloudStorage.get_object_parameters to customize blob parameters for all blobs and per-blob respectively. (#970_)NotFound exception raised when deleting a non-existent blob, this matches Django and other backends (#998, #999)#994_)write_mode param (#1020_).. _fbe9538: https://github.com/jschneier/django-storages/commit/fbe9538b8574cfb0d95b04c9c477650dbfe8547b .. _66f4f8e: https://github.com/jschneier/django-storages/commit/66f4f8ec68daaac767c013d6b1a30cf26a7ac1ca .. _#1003: https://github.com/jschneier/django-storages/pull/1003 .. _#1054: https://github.com/jschneier/django-storages/pull/1054 .. _#1026: https://github.com/jschneier/django-storages/pull/1026 .. _#1041: https://github.com/jschneier/django-storages/pull/1041 .. _#970: https://github.com/jschneier/django-storages/pull/970 .. _#998: https://github.com/jschneier/django-storages/issues/998 .. _#784: https://github.com/jschneier/django-storages/issues/784 .. _#805: https://github.com/jschneier/django-storages/pull/805 .. _#999: https://github.com/jschneier/django-storages/pull/999 .. _#1051: https://github.com/jschneier/django-storages/pull/1051 .. _#1042: https://github.com/jschneier/django-storages/pull/1042 .. _#1046: https://github.com/jschneier/django-storages/issues/1046 .. _#1005: https://github.com/jschneier/django-storages/pull/1005 .. _#1020: https://github.com/jschneier/django-storages/pull/1020 .. _#860: https://github.com/jschneier/django-storages/issues/860 .. _#1057: https://github.com/jschneier/django-storages/pull/1057 .. _#938: https://github.com/jschneier/django-storages/pull/938 .. _#994: https://github.com/jschneier/django-storages/pull/994 .. _#1063: https://github.com/jschneier/django-storages/pull/1063
1.11.1 (2020-12-23)
ValueError: I/O operation on closed file when calling collectstatic and
introduce S3StaticStorage and S3ManifestStaticStorage for use as STATICFILES_STORAGE targets (#968_).. _#968: https://github.com/jschneier/django-storages/pull/968
1.11 (2020-12-16)
#964_)ValueError: I/O operation on closed file when calling collectstatic (#382, #955)S3Boto3StorageFile.buffer_size (via setting AWS_S3_FILE_BUFFER_SIZE)
at run-time rather than import-time. (#930_)bytearray content (#958, #965)GS_QUERYSTRING_AUTH to avoid signing URLs. This is useful for buckets with a
policy of Uniform public read (#952_)AZURE_OBJECT_PARAMETERS and overridable AzureStorage.get_object_parameters to customize
ContentSettings parameters for all keys and per-key respectively. (#898_).. _#382: https://github.com/jschneier/django-storages/issues/382 .. _#955: https://github.com/jschneier/django-storages/pull/955 .. _#930: https://github.com/jschneier/django-storages/pull/930 .. _#952: https://github.com/jschneier/django-storages/pull/952 .. _#898: https://github.com/jschneier/django-storages/pull/898 .. _#964: https://github.com/jschneier/django-storages/pull/964 .. _#958: https://github.com/jschneier/django-storages/issues/958 .. _#965: https://github.com/jschneier/django-storages/pull/965
1.10.1 (2020-09-13)
AWS_DEFAULT_ACL handling. This setting is ignored if ACL is set in
AWS_S3_OBJECT_PARAMETERS (#934_)SFTP_STORAGE_HOST (#926_).. _#926: https://github.com/jschneier/django-storages/pull/926 .. _#934: https://github.com/jschneier/django-storages/pull/934
1.10 (2020-08-30)
#709_)#891_)#916_)BaseStorage class with a get_default_settings method and use
it in S3Boto3Storage, AzureStorage, GoogleCloudStorage, and SFTPStorage. These backends
now calculate their settings when instantiated, not imported. (#524, #852)AWS_BUCKET_ACL and AWS_AUTO_CREATE_BUCKET settings have been removed. (#636_)AWS_PRELOAD_METADATA has been removed (#636_)acl is no longer accepted. Instead, use the ACL key in setting AWS_S3_OBJECT_PARAMETERS
(#636_)bucket is no longer accepted. Instead, use bucket_name or the AWS_STORAGE_BUCKET_NAME
setting (#636_)AWS_REDUCED_REDUNDANCY has been removed. Replace with StorageClass=REDUCED_REDUNDANCY
in AWS_S3_OBJECT_PARAMETERS (#636_)AWS_S3_ENCRYPTION has been removed. Replace with ServerSideEncryption=AES256 in AWS_S3_OBJECT_PARAMETERS (#636_)AWS_DEFAULT_ACL has been removed. Replace with ACL in AWS_S3_OBJECT_PARAMETERS (#636_)http_method parameter to .url method (#854_).url method. You must set AWS_CLOUDFRONT_KEY,
AWS_CLOUDFRONT_KEY_ID and install either cryptography_ or rsa_ (#456, #587). See the docs for more info.
URLs will only be signed if AWS_QUERYSTRING_AUTH is set to True (#885_)GS_AUTO_CREATE_BUCKET and GS_AUTO_CREATE_ACL settings have been removed. (#894_)DROPBOX_WRITE_MODE setting to control e.g. overwriting behavior. Check the docs
for more info (#873, #138)#835, #838)FTP_STORAGE_ENCODING setting to set the filesystem encoding (#803_)#886_).. _cryptography: https://cryptography.io .. _rsa: https://stuvel.eu/rsa .. _#885: https://github.com/jschneier/django-storages/pull/885 .. _#894: https://github.com/jschneier/django-storages/pull/894 .. _#636: https://github.com/jschneier/django-storages/pull/636 .. _#709: https://github.com/jschneier/django-storages/pull/709 .. _#891: https://github.com/jschneier/django-storages/pull/891 .. _#916: https://github.com/jschneier/django-storages/pull/916 .. _#852: https://github.com/jschneier/django-storages/pull/852 .. _#873: https://github.com/jschneier/django-storages/pull/873 .. _#854: https://github.com/jschneier/django-storages/pull/854 .. _#138: https://github.com/jschneier/django-storages/issues/138 .. _#524: https://github.com/jschneier/django-storages/pull/524 .. _#835: https://github.com/jschneier/django-storages/issues/835 .. _#838: https://github.com/jschneier/django-storages/pull/838 .. _#803: https://github.com/jschneier/django-storages/pull/803 .. _#456: https://github.com/jschneier/django-storages/issues/456 .. _#587: https://github.com/jschneier/django-storages/pull/587 .. _#886: https://github.com/jschneier/django-storages/pull/886
1.9.1 (2020-02-03)
S3Boto3StorageFile (#831, #833).. _#831: https://github.com/jschneier/django-storages/issues/831 .. _#833: https://github.com/jschneier/django-storages/pull/833
1.9 (2020-02-02)
boto has been removed. (#825_)#810_)#826_)AWS_PRELOAD_METADATA and associated functionality will
be removed in version 1.10 (#829_)AWS_REDUCED_REDUNDANCY will be removed in version 1.10
Replace with StorageClass=REDUCED_REDUNDANCY in AWS_S3_OBJECT_PARAMETERS (#829_)AWS_S3_ENCRYPTION will be removed in version 1.10 (#829_)
Replace with ServerSideEncryption=AES256 in AWS_S3_OBJECT_PARAMETERSContentEncoding is no longer overwritten automatically (note that specifying
one will disable automatic gzip) (#391, #828).S3Boto3Storage.get_object_parameters, an overridable method for customizing
upload parameters on a per-object basis (#819, #828)w mode without writing anything will now create an empty file
in S3, this mimics the builtin open and Django's own FileSystemStorage (#435, #816)#404, #827)#826_)DropBoxStorage.listdir (#762_)#745_)LibCloudStorage.url (#807_)#823, #824).. _#825: https://github.com/jschneier/django-storages/pull/825 .. _#826: https://github.com/jschneier/django-storages/pull/826 .. _#829: https://github.com/jschneier/django-storages/pull/829 .. _#391: https://github.com/jschneier/django-storages/issues/391 .. _#828: https://github.com/jschneier/django-storages/pull/828 .. _#819: https://github.com/jschneier/django-storages/issues/819 .. _#810: https://github.com/jschneier/django-storages/pull/810 .. _#435: https://github.com/jschneier/django-storages/issues/435 .. _#816: https://github.com/jschneier/django-storages/pull/816 .. _#404: https://github.com/jschneier/django-storages/issues/404 .. _#827: https://github.com/jschneier/django-storages/pull/827 .. _#762: https://github.com/jschneier/django-storages/pull/762 .. _#745: https://github.com/jschneier/django-storages/pull/745 .. _#807: https://github.com/jschneier/django-storages/pull/807 .. _#823: https://github.com/jschneier/django-storages/issues/823 .. _#824: https://github.com/jschneier/django-storages/pull/824
1.8 (2019-11-20)
#759_)BSD-3-Clause#776, #793)google-cloud-storage is now 1.15.0 which enables...GS_CUSTOM_ENDPOINT to allow usage of custom domains (#775, #648)#785_)AZURE_CACHE_CONTROL header (#780, #674).. _#759: https://github.com/jschneier/django-storages/pull/759 .. _#776: https://github.com/jschneier/django-storages/issues/776 .. _#793: https://github.com/jschneier/django-storages/pull/793 .. _#775: https://github.com/jschneier/django-storages/issues/775 .. _#648: https://github.com/jschneier/django-storages/pull/648 .. _#785: https://github.com/jschneier/django-storages/pull/785 .. _#780: https://github.com/jschneier/django-storages/pull/780 .. _#674: https://github.com/jschneier/django-storages/issues/674
1.7.2 (2019-09-10)
AWS_DEFAULT_ACL warning for insecure default_acl when
overridden as a class variable (#591_)preload_metadata is True,
(not the default) (#743, #749)ManifestFilesMixin or
collectstatic. (#382, #754)extra_requires when installing the azure extra to only
azure-storage-blob (#680, #684)generate_blob_shared_access_signature updated signature (#705, #723)#727_)AZURE_ENDPOINT_SUFFIX,
AZURE_CUSTOM_DOMAIN, AZURE_CONNECTION_STRING, AZURE_TOKEN_CREDENTIAL.
See the docs for more info. Huge thanks once again to @nitely. (#750_)#609, #752)#698_)GS_AUTO_CREATE_BUCKET is
False (the default) (#412, #718)predefined_acl when creating a GoogleCloudFile using .write
(#640, #756)GS_BLOB_CHUNK_SIZE setting to enable efficient uploading of large files (#757_)#724_)DROPBOX_TIMEOUT to configure client timeout defaulting to 100 seconds
to match the underlying sdk. (#419, #747)#746_).. _#591: https://github.com/jschneier/django-storages/pull/591 .. _#680: https://github.com/jschneier/django-storages/issues/680 .. _#684: https://github.com/jschneier/django-storages/pull/684 .. _#698: https://github.com/jschneier/django-storages/pull/698 .. _#705: https://github.com/jschneier/django-storages/issues/705 .. _#723: https://github.com/jschneier/django-storages/pull/723 .. _#727: https://github.com/jschneier/django-storages/pull/727 .. _#746: https://github.com/jschneier/django-storages/pull/746 .. _#724: https://github.com/jschneier/django-storages/pull/724 .. _#412: https://github.com/jschneier/django-storages/pull/412 .. _#718: https://github.com/jschneier/django-storages/pull/718 .. _#743: https://github.com/jschneier/django-storages/issues/743 .. _#749: https://github.com/jschneier/django-storages/pull/749 .. _#750: https://github.com/jschneier/django-storages/pull/750 .. _#609: https://github.com/jschneier/django-storages/issues/609 .. _#752: https://github.com/jschneier/django-storages/pull/752 .. _#382: https://github.com/jschneier/django-storages/issues/382 .. _#754: https://github.com/jschneier/django-storages/pull/754 .. _#419: https://github.com/jschneier/django-storages/issues/419 .. _#747: https://github.com/jschneier/django-storages/pull/747 .. _#640: https://github.com/jschneier/django-storages/issues/640 .. _#756: https://github.com/jschneier/django-storages/pull/756 .. _#757: https://github.com/jschneier/django-storages/pull/757
1.7.1 (2018-09-06)
get_available_name whenever file_overwrite or overwrite_files is True (#588, #589)S3Boto3Storage.listdir() to use list_objects instead of list_objects_v2 to restore
compatibility with services implementing the S3 protocol that do not yet support the new method (#586, #590).. _#588: https://github.com/jschneier/django-storages/issues/588 .. _#589: https://github.com/jschneier/django-storages/pull/589 .. _#586: https://github.com/jschneier/django-storages/issues/586 .. _#590: https://github.com/jschneier/django-storages/pull/590
1.7 (2018-09-03)
Security
S3BotoStorage and S3Boto3Storage backends have an insecure
default ACL of public-read. It is recommended that all current users audit their bucket
permissions. Support has been added for setting AWS_DEFAULT_ACL = None and AWS_BUCKET_ACL = None which causes all created files to inherit the bucket's ACL (and created buckets to inherit the
Amazon account's default ACL). This will become the default in version 1.10 (for S3Boto3Storage only
since S3BotoStorage will be removed in version 1.9, see below). Additionally, a warning is now
raised if AWS_DEFAULT_ACL or AWS_BUCKET_ACL is not explicitly set. (#381, #535, #579_)Breaking
AzureStorage backend and documentation has been completely rewritten. It now
depends on azure and azure-storage-blob and is vastly improved. Big thanks to @nitely and all
other contributors along the way (#565_).url() method of GoogleCloudStorage has been completely reworked. Many use
cases should require no changes and will experience a massive speedup. The .url() method no longer hits
the network for public urls and generates signed urls (with a default of 1-day expiration, configurable
via GS_EXPIRATION) for non-public buckets. Check out the docs for more information. (#570_)ImproperlyConfigured at runtime if their
location (GS_LOCATION, AWS_LOCATION) begins with a leading / rather than silently
stripping it. Verify yours does not. (#520_)GSBotoStorage backend is removed. (#518_)Deprecation
public-read for AWS_DEFAULT_ACL and
AWS_BUCKET_ACL in S3Boto3Storage will change to inherit the bucket's setting in version 1.10 (#579_)S3BotoBackend is deprecated and will be removed in version 1.9.
It is strongly recommended to move to the S3Boto3Storage backend for performance,
stability and bugfix reasons. See the boto migration docs_ for step-by-step guidelines. (#578, #584)S3Boto3Storage of acl and bucket are
deprecated in favor of bucket_name and default_acl (#516_)boto3 will be increasing to 1.4.4 in
the next major version of django-storages. (#583_)Features
AWS_DEFAULT_ACL = None (#535_)GS_CACHE_CONTROL setting for GoogleCloudStorage backend (#411, #505)#521_)#530_)S3Boto3Storage pickleable (#551_)SFTPStorage (#563, #564)b13efd_).listdir on S3Boto3Storage (#352_)AWS_S3_VERIFY to support custom certificates and disabling certificate verification
to S3Boto3Storage (#486, #580)AWS_S3_PROXIES setting to S3Boto3Storage (#583_)Bugfixes
GoogleCloudStorage and AzureStorage (#481, #581, #582_)#169, #160, #364, #449, #504, #506, #546_)S3Boto3Storage to stream down large files (also disallow r+w mode) (#383, #548)SFTPStorageFile to align with the core File abstraction (#487, #568)IOError in SFTPStorage.delete (#568_)AzureStorage, GoogleCloudStorage, S3Boto3Storage and S3BotoStorage now
respect max_length when file_overwrite = True (#513, #554)compresslevel=9 (the Python stdlib default)
for gzipped content (#572, #576)S3Boto3Storage during an unexpected exception when automatically
creating a bucket (#574, #577).. _#381: https://github.com/jschneier/django-storages/issues/381 .. _#535: https://github.com/jschneier/django-storages/pull/535 .. _#579: https://github.com/jschneier/django-storages/pull/579 .. _#565: https://github.com/jschneier/django-storages/pull/565 .. _#520: https://github.com/jschneier/django-storages/pull/520 .. _#518: https://github.com/jschneier/django-storages/pull/518 .. _#516: https://github.com/jschneier/django-storages/pull/516 .. _#481: https://github.com/jschneier/django-storages/pull/481 .. _#581: https://github.com/jschneier/django-storages/pull/581 .. _#582: https://github.com/jschneier/django-storages/pull/582 .. _#411: https://github.com/jschneier/django-storages/issues/411 .. _#505: https://github.com/jschneier/django-storages/pull/505 .. _#521: https://github.com/jschneier/django-storages/pull/521 .. _#169: https://github.com/jschneier/django-storages/pull/169 .. _#160: https://github.com/jschneier/django-storages/issues/160 .. _#364: https://github.com/jschneier/django-storages/pull/364 .. _#449: https://github.com/jschneier/django-storages/issues/449 .. _#504: https://github.com/jschneier/django-storages/pull/504 .. _#530: https://github.com/jschneier/django-storages/pull/530 .. _#506: https://github.com/jschneier/django-storages/pull/506 .. _#546: https://github.com/jschneier/django-storages/pull/546 .. _#383: https://github.com/jschneier/django-storages/issues/383 .. _#548: https://github.com/jschneier/django-storages/pull/548 .. _b13efd: https://github.com/jschneier/django-storages/commit/b13efd92b3bf3e9967b8e7819224bfcf9abb977e .. _#551: https://github.com/jschneier/django-storages/pull/551 .. _#563: https://github.com/jschneier/django-storages/issues/563 .. _#564: https://github.com/jschneier/django-storages/pull/564 .. _#487: https://github.com/jschneier/django-storages/issues/487 .. _#568: https://github.com/jschneier/django-storages/pull/568 .. _#513: https://github.com/jschneier/django-storages/issues/513 .. _#554: https://github.com/jschneier/django-storages/pull/554 .. _#570: https://github.com/jschneier/django-storages/pull/570 .. _#572: https://github.com/jschneier/django-storages/issues/572 .. _#576: https://github.com/jschneier/django-storages/pull/576 .. _#352: https://github.com/jschneier/django-storages/pull/352 .. _#574: https://github.com/jschneier/django-storages/issues/574 .. _#577: https://github.com/jschneier/django-storages/pull/577 .. _#486: https://github.com/jschneier/django-storages/pull/486 .. _#580: https://github.com/jschneier/django-storages/pull/580 .. _#583: https://github.com/jschneier/django-storages/pull/583 .. _boto migration docs: https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#migrating-boto-to-boto3 .. _#578: https://github.com/jschneier/django-storages/pull/578 .. _#584: https://github.com/jschneier/django-storages/pull/584
1.6.6 (2018-03-26)
extra_requires. For example pip install django-storages[boto3] (#417_)#406, #407)GS_LOCATION setting to specify subdirectory for GoogleCloudStorage (#355_)DropBoxStorage, fix saving files (#379, #378, #301_)#438_)get_created_time for GoogleCloudStorage (#464_).. _#417: https://github.com/jschneier/django-storages/pull/417 .. _#407: https://github.com/jschneier/django-storages/pull/407 .. _#406: https://github.com/jschneier/django-storages/issues/406 .. _#355: https://github.com/jschneier/django-storages/pull/355 .. _#379: https://github.com/jschneier/django-storages/pull/379 .. _#378: https://github.com/jschneier/django-storages/issues/378 .. _#301: https://github.com/jschneier/django-storages/issues/301 .. _#438: https://github.com/jschneier/django-storages/issues/438 .. _#464: https://github.com/jschneier/django-storages/pull/464
1.6.5 (2017-08-01)
#367, #371, #373_)mtime when gzipping content on S3Boto3Storage (#374_).. _#367: https://github.com/jschneier/django-storages/issues/367 .. _#371: https://github.com/jschneier/django-storages/pull/371 .. _#373: https://github.com/jschneier/django-storages/pull/373 .. _#374: https://github.com/jschneier/django-storages/pull/374
1.6.4 (2017-07-27)
GoogleCloudStorage will now set their appropriate mimetype (#320_)DropBoxStorage.url to work. (#357_)S3Boto3Storage when AWS_PRELOAD_METADATA = True (#366_)S3Boto3Storage uploading file-like objects without names (#195, #368)S3Boto3Storage is now threadsafe - a separate session is created on a
per-thread basis (#268, #358).. _#320: https://github.com/jschneier/django-storages/pull/320 .. _#357: https://github.com/jschneier/django-storages/pull/357 .. _#366: https://github.com/jschneier/django-storages/pull/366 .. _#195: https://github.com/jschneier/django-storages/pull/195 .. _#368: https://github.com/jschneier/django-storages/pull/368 .. _#268: https://github.com/jschneier/django-storages/issues/268 .. _#358: https://github.com/jschneier/django-storages/pull/358
1.6.3 (2017-06-23)
AWS_S3_SIGNATURE_VERSION to V2 to restore backwards
compatibility in S3Boto3. It's recommended that all new projects set
this to be 's3v4'. (#344_).. _#344: https://github.com/jschneier/django-storages/pull/344
1.6.2 (2017-06-22)
safe_join() to handle a trailing slash in an
intermediate path. (#341_)gs.GSBotoStorage getting an unexpected kwarg.
(#342_).. _#341: https://github.com/jschneier/django-storages/pull/341 .. _#342: https://github.com/jschneier/django-storages/pull/342
1.6.1 (2017-06-22)
e89db45_)safe_join() to allow joining a base path with an empty
string. (#336_).. _e89db45: https://github.com/jschneier/django-storages/commit/e89db451d7e617638b5991e31df4c8de196546a6 .. _#336: https://github.com/jschneier/django-storages/pull/336
1.6 (2017-06-21)
#280_)DropBoxStorage has been upgrade to support v2 of the API, v1 will be shut off at the
end of the month - upgrading is recommended (#273_)SFTPStorage backend now checks for the existence of the fallback ~/.ssh/known_hosts
before attempting to load it. If you had previously been passing in a path to a non-existent file it will no longer
attempt to load the fallback. (#118, #325)AWS_S3_SIGNATURE_VERSION is now 's3v4'. No changes should
be required (#335_)gs.GSBotoStorage backend. See the new gcloud.GoogleCloudStorage
or apache_libcloud.LibCloudStorage backends instead. (#236_)gcloud.GoogleCloudStorage based on the google-cloud bindings. (#236_)S3Boto3Storage (#257, #258)AWS_SESSION_TOKEN and AWS_SECURITY_TOKEN from the environment
to S3Boto3Storage and S3BotoStorage. (#283_)#216, #217)collectstatic timezone handling in and add get_modified_time to S3BotoStorage (#290_)#295_)project keyword support to GCS in LibCloudStorage backend (#269_)s3boto3 backend (#263, #264)e52a127_)#248, #322).. _#217: https://github.com/jschneier/django-storages/pull/217 .. _#273: https://github.com/jschneier/django-storages/pull/273 .. _#216: https://github.com/jschneier/django-storages/issues/216 .. _#283: https://github.com/jschneier/django-storages/pull/283 .. _#280: https://github.com/jschneier/django-storages/pull/280 .. _#257: https://github.com/jschneier/django-storages/issues/257 .. _#258: https://github.com/jschneier/django-storages/pull/258 .. _#290: https://github.com/jschneier/django-storages/pull/290 .. _#295: https://github.com/jschneier/django-storages/pull/295 .. _#269: https://github.com/jschneier/django-storages/pull/269 .. _#263: https://github.com/jschneier/django-storages/issues/263 .. _#264: https://github.com/jschneier/django-storages/pull/264 .. _e52a127: https://github.com/jschneier/django-storages/commit/e52a127523fdd5be50bb670ccad566c5d527f3d1 .. _#236: https://github.com/jschneier/django-storages/pull/236 .. _#118: https://github.com/jschneier/django-storages/issues/118 .. _#325: https://github.com/jschneier/django-storages/pull/325 .. _#248: https://github.com/jschneier/django-storages/issues/248 .. _#322: https://github.com/jschneier/django-storages/pull/322 .. _#335: https://github.com/jschneier/django-storages/pull/335
1.5.2 (2017-01-13)
SFTP_STORAGE_HOST in SFTPStorage backend (#204_)S3Boto3Storage to avoid race conditions in a multi-threaded WSGI environment (#238_)settings.USE_TZ is False in S3Boto3Storage.modified_time.
(#235, #234)S3Boto3Storage when AWS_AUTO_CREATE_BUCKET is True (#196_).. _#204: https://github.com/jschneier/django-storages/pull/204 .. _#238: https://github.com/jschneier/django-storages/pull/238 .. _#234: https://github.com/jschneier/django-storages/issues/234 .. _#235: https://github.com/jschneier/django-storages/pull/235 .. _#196: https://github.com/jschneier/django-storages/pull/196
1.5.1 (2016-09-13)
#185_)#202_) to discuss maintenance going forwardmtime argument for GzipFile in S3BotoStorage and S3Boto3Storage to ensure
a stable output for gzipped files.putfileobj instead of .put in S3Boto3Storage to use the transfer manager,
allowing files greater than 5GB to be put on S3 (#194_ , #201_)S3Boto3Storage for Django 1.10 (#181_) (get_modified_time and get_accessed_time)S3Boto3Storage when AWS_PRELOAD_METADATA is True (#189, #190).. _#202: https://github.com/jschneier/django-storages/issues/202 .. _#201: https://github.com/jschneier/django-storages/pull/201 .. _#194: https://github.com/jschneier/django-storages/issues/194 .. _#190: https://github.com/jschneier/django-storages/pull/190 .. _#189: https://github.com/jschneier/django-storages/issues/189 .. _#185: https://github.com/jschneier/django-storages/pull/185 .. _#181: https://github.com/jschneier/django-storages/pull/181
1.5.0 (2016-08-02)
S3Boto3Storage (#179_)strict option to utils.setting (#176_).close for SFTPStorage (#177_).readlines for FTPStorage (#175_)DropBoxStorage (#174_)MANIFEST.in to not ship .pyc files. (#145_)#171_).. _#145: https://github.com/jschneier/django-storages/pull/145 .. _#171: https://github.com/jschneier/django-storages/pull/171 .. _#174: https://github.com/jschneier/django-storages/pull/174 .. _#175: https://github.com/jschneier/django-storages/pull/175 .. _#177: https://github.com/jschneier/django-storages/pull/177 .. _#176: https://github.com/jschneier/django-storages/pull/176 .. _#179: https://github.com/jschneier/django-storages/pull/179
1.4.1 (2016-04-07)
s3boto backend. Compressable types such as application/javascript will still be gzipped.
PR #122_DropBoxStorage.exists check and add DropBoxStorage.url (#127_)GS_HOST setting (with a default of GSConnection.DefaultHost) to fix GSBotoStorage.
(#124, #125).. _#122: https://github.com/jschneier/django-storages/pull/122 .. _#127: https://github.com/jschneier/django-storages/pull/127 .. _#124: https://github.com/jschneier/django-storages/issues/124 .. _#125: https://github.com/jschneier/django-storages/pull/125
1.4 (2016-02-07)
django-storages. Please update your requirements files to
django-storages==1.4.1.3.2 (2016-01-26)
s3boto backend (#106_)S3BotoStorage (#96_)storage.exists in S3BotoStorage -
this prevents a crash when running collectstatic -c on Django 1.9.1 (#112) fixed in #116.. _#106: https://github.com/jschneier/django-storages/pull/106 .. _#96: https://github.com/jschneier/django-storages/pull/96 .. _#112: https://github.com/jschneier/django-storages/issues/112 .. _#116: https://github.com/jschneier/django-storages/pull/116
1.3.1 (2016-01-12)
url] (#45__)dropbox) storage backendapache_libcloud backend [return the number of bytes asked for by .read, make .name non-private, don't
initialize to an empty BytesIO object] (#55_)s3boto backend not respecting AWS_S3_ENCRYPTION (#94_)#100_).. __: https://github.com/jschneier/django-storages/pull/45 .. _#76: https://github.com/jschneier/django-storages/pull/76 .. _#55: https://github.com/jschneier/django-storages/pull/55 .. _#94: https://github.com/jschneier/django-storages/pull/94 .. _#100: https://github.com/jschneier/django-storages/pull/100
1.3 (2015-08-14)
parse_ts_extended from s3boto storage#36__)AWS_S3_PROXY_HOST and AWS_S3_PROXY_PORT settings for s3boto backend (#41_)#52_)GS_IS_GZIPPED setting (#51__, #60_)_name attribute to name which is what the Django File api is expecting (#70_)StorageMixin first in inheritance to maintain backwards compat with older versions of Django (#63_).. __: https://github.com/jschneier/django-storages/pull/36 .. _#41: https://github.com/jschneier/django-storages/pull/41 .. _#52: https://github.com/jschneier/django-storages/issues/52 .. __: https://github.com/jschneier/django-storages/pull/51 .. _#60: https://github.com/jschneier/django-storages/pull/60 .. _#70: https://github.com/jschneier/django-storages/pull/70 .. _#63: https://github.com/jschneier/django-storages/pull/63
1.2.3 (2015-03-14)
exists, add modified_time, remove call to non-existent function) (#26_).. _#26: https://github.com/jschneier/django-storages/pull/26
1.2.2 (2015-01-28)
#21_)#20__)S3BotoStorage deconstructible (previously only S3BotoStorageFile was deconstructible) (#19_).. _#21: https://github.com/jschneier/django-storages/pull/21 .. __: https://github.com/jschneier/django-storages/issues/20 .. _#19: https://github.com/jschneier/django-storages/pull/19
1.2.1 (2014-12-31)
parse_ts_extendedstorage.modified_time crashing on new files when AWS_PRELOAD_METADATA=True (#11, #12__, #14).. _#11: https://github.com/jschneier/django-storages/pull/11 __ https://github.com/jschneier/django-storages/issues/12 .. _#14: https://github.com/jschneier/django-storages/pull/14
1.2 (2014-12-14)
#1_)#2_)#5, #8)#4_).. _#8: https://github.com/jschneier/django-storages/pull/8 .. _#5: https://github.com/jschneier/django-storages/pull/5 .. _#4: https://github.com/jschneier/django-storages/pull/4 .. _#1: https://github.com/jschneier/django-storages/issues/1 .. _#2: https://github.com/jschneier/django-storages/issues/2
NOTE: Version 1.1.9 is the first release of django-storages after the fork. It represents the current (2014-12-08) state of the original django-storages in master with no additional changes. This is the first release of the code base since March 2013.
1.1.9 (2014-12-08)
#91_#90_#86_#188_ fixed by pull-request #85_#69_#65_#66_.. _#91: https://bitbucket.org/david/django-storages/pull-request/91/ .. _#90: https://bitbucket.org/david/django-storages/pull-request/90/ .. _#86: https://bitbucket.org/david/django-storages/pull-request/86/ .. _#188: https://bitbucket.org/david/django-storages/issue/188/s3boto-_clean_name-is-broken-and-leads-to .. _#85: https://bitbucket.org/david/django-storages/pull-request/85/ .. _#69: https://bitbucket.org/david/django-storages/pull-request/69/ .. _#66: https://bitbucket.org/david/django-storages/pull-request/66/ .. _#65: https://bitbucket.org/david/django-storages/pull-request/65/
Everything Below Here Was Previously Released on PyPI under django-storages
1.1.8 (2013-03-31)
#156_ regarding date parsing, ValueError when running collectstatic.. _#156: https://bitbucket.org/david/django-storages/issue/156/s3boto-backend-valueerror-time-data-thu-07
1.1.7 (2013-03-20)
#50_.. _#50: https://bitbucket.org/david/django-storages/pull-request/50/
1.1.6 (2013-01-06)
#133_ with pull-request #44_#45_#43_#48_#46_#17_#105_.. _#133: https://bitbucket.org/david/django-storages/issue/133/license-file-refers-to-incorrect-project .. _#44: https://bitbucket.org/david/django-storages/pull-request/44/ .. _#45: https://bitbucket.org/david/django-storages/pull-request/45/ .. _#43: https://bitbucket.org/david/django-storages/pull-request/43/ .. _#48: https://bitbucket.org/david/django-storages/pull-request/48/ .. _#46: https://bitbucket.org/david/django-storages/pull-request/46/ .. _#17: https://bitbucket.org/david/django-storages/pull-request/17/ .. _#105: https://bitbucket.org/david/django-storages/issue/105/add-option-to-produce-protocol-relative
1.1.5 (2012-07-18)
#36_ from freakboy3742 Keith-Magee, improvements to Apache Libcloud backend and docs#35_ from atodorov, allows more granular S3 access settings#57_#20_ from alanjds, fixed SuspiciousOperation warning if AWS_LOCATION ends with '/'#30_ from pendletongp, resolves #108, #109 and #110_#111_#16_ from chamal, adds Apache Libcloud backend#24_ from tobias.mcnulty, fixes bug where s3boto backend returns modified_time in wrong time zone.. _#36: https://bitbucket.org/david/django-storages/pull-request/36/ .. _#35: https://bitbucket.org/david/django-storages/pull-request/35/ .. _#57: https://bitbucket.org/david/django-storages/issue/57 .. _#20: https://bitbucket.org/david/django-storages/pull-request/20/ .. _#30: https://bitbucket.org/david/django-storages/pull-request/30/ .. _#108: https://bitbucket.org/david/django-storages/issue/108 .. _#109: https://bitbucket.org/david/django-storages/issue/109 .. _#110: https://bitbucket.org/david/django-storages/issue/110 .. _#111: https://bitbucket.org/david/django-storages/issue/111 .. _#16: https://bitbucket.org/david/django-storages/pull-request/16/ .. _#24: https://bitbucket.org/david/django-storages/pull-request/24/
1.1.4 (2012-01-06)
#13_ from marcoala, adds SFTP_KNOWN_HOST_FILE setting to SFTP storage backend#12_ from ryankask, fixes HashPathStorage tests that delete remote media#10_ from key, adds support for django-mongodb-engine 0.4.0 or later, fixes GridFS file deletion bug#40_#78_#83_.. _#13: https://bitbucket.org/david/django-storages/pull-request/13/a-version-of-sftp-storage-that-allows-you .. _#12: https://bitbucket.org/david/django-storages/pull-request/12/hashpathstorage-tests-deleted-my-projects .. _#10: https://bitbucket.org/david/django-storages/pull-request/10/support-django-mongodb-engine-040 .. _#40: https://bitbucket.org/david/django-storages/issue/40/deprecate-s3py-backend .. _#78: https://bitbucket.org/david/django-storages/issue/78/import-error .. _#83: https://bitbucket.org/david/django-storages/issue/6/symlinkorcopystorage-new-custom-storage
1.1.3 (2011-08-15)
#89_: broken StringIO import in CloudFiles backendpull request #5_: HashPathStorage path bug.. _#89: https://bitbucket.org/david/django-storages/issue/89/112-broke-the-mosso-backend .. _pull request #5: https://bitbucket.org/david/django-storages/pull-request/5/fixed-path-bug-and-added-testcase-for