.. 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
Installation
============
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'
Once that is done set ``DEFAULT_FILE_STORAGE`` to the backend of your choice.
If, for example, you want to use the boto3 backend you would set:
.. code-block:: python
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
If you are using the ``FileSystemStorage`` as your storage management class in your models ``FileField`` fields, remove them
and don't specify any storage parameter. That way, the ``DEFAULT_FILE_STORAGE`` class will be used by default in your field.
For example, if you have a `photo` field defined as:
.. code-block:: python
photo = models.FileField(
storage=FileSystemStorage(location=settings.MEDIA_ROOT),
upload_to='photos',
)
Set it to just:
.. code-block:: python
photo = models.FileField(
upload_to='photos',
)
There are also a number of settings available to control how each storage backend functions,
please consult the documentation for a comprehensive list.
About
=====
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
Security
========
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
Found a Bug?
============
Issues are tracked via GitHub issues at the `project issue page
<https://github.com/jschneier/django-storages/issues>`_.
Documentation
=============
Documentation for django-storages is located at https://django-storages.readthedocs.io/.
Contributing
============
#. `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``.
History
=======
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.
django-storages CHANGELOG
=========================
1.13.2 (2022-12-23)
*******************
General
-------
- Add support for Python 3.11 (`#1196`_)
- Add support for saving ``pathlib.Path`` names (`#1200`_)
S3
--
- Catch 404 errors when calling ``delete()`` (`#1201`_)
Azure
-----
- Use ``AZURE_CUSTOM_DOMAIN`` for retrieving blob URLs and storage URL for other operations (`#1176`_)
Google Cloud
------------
- Use ``DEFAULT_RETRY`` for all upload & delete operations (`#1156`_)
- Fix gzipping of content (`#1203`_)
- Pass through kwargs to signed URL generator (`#1193`_)
SFTP
----
- Improve write & memory performance when saving files (`#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)
*******************
Dropbox
-------
- Strip off the root path when saving files to fix saving with upgraded versions of Django (`#1168`_)
- Update ``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)
*****************
General
-------
- Add support for Django 4.0 and 4.1 (`#1093`_)
- Drop support for Django 2.2, 3.0 and 3.1 (`#1093`_)
- Drop support for Python 3.5 and 3.6 (`#1093`_)
S3
--
- **Breaking**: Update and document the undocumented ``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`_)
- Add ``AWS_S3_USE_THREADS`` to disable ``threading`` for compatibility with ``gevent`` (`#1112`_)
Dropbox
-------
- Add support for refresh tokens (`#1159`_)
- Ignore ``ApiError`` exception in ``url()`` (`#1158`_)
Azure
-----
- Restore support for ``AZURE_ENDPOINT_SUFFIX`` (`#1118`_)
- Replace deprecated ``download_to_stream`` with ``readinto`` (`#1113`_)
- Add ``AZURE_API_VERSION`` setting (`#1132`_)
- Fix ``get_modified_time()`` (`#1134`_)
Google Cloud
------------
- Add support for gzipping files via ``GS_IS_GZIPPED`` and ``GZIP_CONTENT_TYPES`` (`#980`_)
- Use ``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)
*******************
General
-------
- Add support for Python 3.10 (`#1078`_)
S3
--
- Re-raise non-404 errors in ``.exists()`` (`#1084`_, `#1085`_)
Azure
-----
- Fix using ``AZURE_CUSTOM_DOMAIN`` with an account key credential (`#1082`_, `#1083`_)
SFTP
----
- Catch ``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)
*******************
Azure
-----
- Add ``parameters`` kwarg to ``AzureStorage.url`` to configure blob properties in the SAS token (`#1071`_)
- Fix regression where ``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)
*******************
S3
--
- Change gzip compression to use a streaming implementation (`#1061`_)
- Fix saving files with ``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)
*****************
General
-------
- Add support for Django 3.2 (`#1046`_, `#1042`_, `#1005`_)
- Replace Travis CI with GitHub actions (`#1051`_)
S3
--
- Convert signing keys to bytes if necessary (`#1003`_)
- Avoid a ListParts API call during multipart upload (`#1041`_)
- Custom domains now use passed URL params (`#1054`_)
- Allow the use of AWS profiles and clarify the options for passing credentials (`fbe9538`_)
- Re-allow override of various access key names (`#1026`_)
- Properly exclude empty folders during ``listdir`` (`66f4f8e`_)
- Support saving file objects that are not ``seekable`` (`#860`_, `#1057`_)
- Return ``True`` for ``.exists()`` if a non-404 error is encountered (`#938`_)
Azure
-----
- **Breaking**: This backend has been rewritten to use the newer versions of ``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`_)
- Add support for user delegation keys (`#1063`_)
Google Cloud
------------
- **Breaking**: The minimum required version of ``google-cloud-storage`` is now 1.27.0 (`#994`_)
- **Breaking**: Switch URL signing version from v2 to v4 (`#994`_)
- **Deprecated**: Support for ``GS_CACHE_CONTROL`` will be removed in 1.13. Please set the ``cache_control`` parameter of ``GS_OBJECT_PARAMETERS`` instead. (`#970`_)
- Add ``GS_OBJECT_PARAMETERS`` and overridable ``GoogleCloudStorage.get_object_parameters`` to customize blob parameters for all blobs and per-blob respectively. (`#970`_)
- Catch the ``NotFound`` exception raised when deleting a non-existent blob, this matches Django and other backends (`#998`_, `#999`_)
- Fix signing URLs with custom endpoints (`#994`_)
Dropbox
-------
- Validate ``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)
*******************
S3
--
- Revert fix for ``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)
*****************
General
-------
- Test against Python 3.9 (`#964`_)
S3
--
- Fix ``ValueError: I/O operation on closed file`` when calling ``collectstatic`` (`#382`_, `#955`_)
- Calculate ``S3Boto3StorageFile.buffer_size`` (via setting ``AWS_S3_FILE_BUFFER_SIZE``)
at run-time rather than import-time. (`#930`_)
- Fix writing ``bytearray`` content (`#958`_, `#965`_)
Google Cloud
------------
- Add setting ``GS_QUERYSTRING_AUTH`` to avoid signing URLs. This is useful for buckets with a
policy of Uniform public read (`#952`_)
Azure
-----
- Add ``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)
*******************
S3
--
- Restore ``AWS_DEFAULT_ACL`` handling. This setting is ignored if ``ACL`` is set in
``AWS_S3_OBJECT_PARAMETERS`` (`#934`_)
SFTP
----
- Fix using ``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)
*****************
General
-------
- **Breaking**: Removed support for end-of-life Python 2.7 and 3.4 (`#709`_)
- **Breaking**: Removed support for end-of-life Django 1.11 (`#891`_)
- Add support for Django 3.1 (`#916`_)
- Introduce a new ``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`_)
S3
--
- **Breaking**: Automatic bucket creation has been removed. Doing so encourages using overly broad credentials.
As a result, support for the corresponding ``AWS_BUCKET_ACL`` and ``AWS_AUTO_CREATE_BUCKET`` settings have been removed. (`#636`_)
- **Breaking**: Support for the undocumented setting ``AWS_PRELOAD_METADATA`` has been removed (`#636`_)
- **Breaking**: The constructor kwarg ``acl`` is no longer accepted. Instead, use the ``ACL`` key in setting ``AWS_S3_OBJECT_PARAMETERS``
(`#636`_)
- **Breaking**: The constructor kwarg ``bucket`` is no longer accepted. Instead, use ``bucket_name`` or the ``AWS_STORAGE_BUCKET_NAME``
setting (`#636`_)
- **Breaking**: Support for setting ``AWS_REDUCED_REDUNDANCY`` has been removed. Replace with ``StorageClass=REDUCED_REDUNDANCY``
in ``AWS_S3_OBJECT_PARAMETERS`` (`#636`_)
- **Breaking**: Support for setting ``AWS_S3_ENCRYPTION`` has been removed. Replace with ``ServerSideEncryption=AES256`` in ``AWS_S3_OBJECT_PARAMETERS`` (`#636`_)
- **Breaking**: Support for setting ``AWS_DEFAULT_ACL`` has been removed. Replace with ``ACL`` in ``AWS_S3_OBJECT_PARAMETERS`` (`#636`_)
- Add ``http_method`` parameter to ``.url`` method (`#854`_)
- Add support for signing Cloudfront URLs to the ``.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`_)
Google Cloud
------------
- **Breaking**: Automatic bucket creation has been removed. Doing so encourages using overly broad credentials.
As a result, support for the corresponding ``GS_AUTO_CREATE_BUCKET`` and ``GS_AUTO_CREATE_ACL`` settings have been removed. (`#894`_)
Dropbox
-------
- Add ``DROPBOX_WRITE_MODE`` setting to control e.g. overwriting behavior. Check the docs
for more info (`#873`_, `#138`_)
SFTP
----
- Remove exception swallowing during ssh connection (`#835`_, `#838`_)
FTP
---
- Add ``FTP_STORAGE_ENCODING`` setting to set the filesystem encoding (`#803`_)
- Support multiple nested paths for files (`#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)
******************
S3
--
- Fix reading files with ``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)
****************
General
-------
- **Breaking**: The long deprecated S3 backend based on ``boto`` has been removed. (`#825`_)
- Test against and support Python 3.8 (`#810`_)
S3
--
- **Deprecated**: Automatic bucket creation will be removed in version 1.10 (`#826`_)
- **Deprecated**: The undocumented ``AWS_PRELOAD_METADATA`` and associated functionality will
be removed in version 1.10 (`#829`_)
- **Deprecated**: Support for ``AWS_REDUCED_REDUNDANCY`` will be removed in version 1.10
Replace with ``StorageClass=REDUCED_REDUNDANCY`` in ``AWS_S3_OBJECT_PARAMETERS`` (`#829`_)
- **Deprecated**: Support for ``AWS_S3_ENCRYPTION`` will be removed in version 1.10 (`#829`_)
Replace with ``ServerSideEncryption=AES256`` in ``AWS_S3_OBJECT_PARAMETERS``
- A custom ``ContentEncoding`` is no longer overwritten automatically (note that specifying
one will disable automatic ``gzip``) (`#391`_, `#828`_).
- Add ``S3Boto3Storage.get_object_parameters``, an overridable method for customizing
upload parameters on a per-object basis (`#819`_, `#828`_)
- Opening and closing a file in `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`_)
- Fix reading a file in text mode (`#404`_, `#827`_)
Google Cloud
------------
- **Deprecated**: Automatic bucket creation will be removed in version 1.10 (`#826`_)
Dropbox
-------
- Fix crash on ``DropBoxStorage.listdir`` (`#762`_)
- Settings can now additionally be specified at the class level to ease subclassing (`#745`_)
Libcloud
--------
- Add support for Backblaze B2 to ``LibCloudStorage.url`` (`#807`_)
FTP
---
- Fix creating multiple intermediary directories on Windows (`#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)
****************
General
-------
- Add support for Django 3.0 (`#759`_)
- Update license identifier to unambiguous ``BSD-3-Clause``
S3
--
- Include error message raised when missing library is imported (`#776`_, `#793`_)
Google
------
- **Breaking** The minimum supported version of ``google-cloud-storage`` is now ``1.15.0`` which enables...
- Add setting ``GS_CUSTOM_ENDPOINT`` to allow usage of custom domains (`#775`_, `#648`_)
Azure
-----
- Fix extra installation by pinning version to < 12 (`#785`_)
- Add support for setting ``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)
******************
S3
--
- Avoid misleading ``AWS_DEFAULT_ACL`` warning for insecure ``default_acl`` when
overridden as a class variable (`#591`_)
- Propagate file deletion to cache when ``preload_metadata`` is ``True``,
(not the default) (`#743`_, `#749`_)
- Fix exception raised on closed file (common if using ``ManifestFilesMixin`` or
``collectstatic``. (`#382`_, `#754`_)
Azure
-----
- Pare down the required packages in ``extra_requires`` when installing the ``azure`` extra to only
``azure-storage-blob`` (`#680`_, `#684`_)
- Fix compatability with ``generate_blob_shared_access_signature`` updated signature (`#705`_, `#723`_)
- Fetching a file now uses the configured timeout rather than hardcoding one (`#727`_)
- Add support for configuring all blobservice options: ``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`_)
- Fix filename handling to not strip special characters (`#609`_, `#752`_)
Google Cloud
------------
- Set the file acl in the same call that uploads it (`#698`_)
- Reduce the number of queries and required permissions when ``GS_AUTO_CREATE_BUCKET`` is
``False`` (the default) (`#412`_, `#718`_)
- Set the ``predefined_acl`` when creating a ``GoogleCloudFile`` using ``.write``
(`#640`_, `#756`_)
- Add ``GS_BLOB_CHUNK_SIZE`` setting to enable efficient uploading of large files (`#757`_)
Dropbox
-------
- Complete migration to v2 api with file fetching and metadata fixes (`#724`_)
- Add ``DROPBOX_TIMEOUT`` to configure client timeout defaulting to 100 seconds
to match the underlying sdk. (`#419`_, `#747`_)
SFTP
----
- Fix reopening a file (`#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)
******************
- Fix off-by-1 error in ``get_available_name`` whenever ``file_overwrite`` or ``overwrite_files`` is ``True`` (`#588`_, `#589`_)
- Change ``S3Boto3Storage.listdir()`` to use ``list_objects`` instead of ``list_objects_v2`` to restore
compatability 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**
- The ``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**
- The ``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`_)
- The ``.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`_)
- Various backends will now raise ``ImproperlyConfigured`` at runtime if their
location (``GS_LOCATION``, ``AWS_LOCATION``) begins with a leading ``/`` rather than silently
stripping it. Verify yours does not. (`#520`_)
- The long deprecated ``GSBotoStorage`` backend is removed. (`#518`_)
**Deprecation**
- The insecure default of ``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`_)
- The legacy ``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`_)
- The long aliased arguments to ``S3Boto3Storage`` of ``acl`` and ``bucket`` are
deprecated in favor of ``bucket_name`` and ``default_acl`` (`#516`_)
- The minimum required version of ``boto3`` will be increasing to ``1.4.4`` in
the next major version of ``django-storages``. (`#583`_)
**Features**
- Add support for a file to inherit its bucket's ACL by setting ``AWS_DEFAULT_ACL = None`` (`#535`_)
- Add ``GS_CACHE_CONTROL`` setting for ``GoogleCloudStorage`` backend (`#411`_, `#505`_)
- Add documentation around using django-storages with Digital Ocean Spaces (`#521`_)
- Add support for Django 2.1 and Python 3.7 (`#530`_)
- Make ``S3Boto3Storage`` pickleable (`#551`_)
- Add automatic reconnection to ``SFTPStorage`` (`#563`_, `#564`_)
- Unconditionally set the security token in the boto backends (`b13efd`_)
- Improve efficiency of ``.listdir`` on ``S3Boto3Storage`` (`#352`_)
- Add ``AWS_S3_VERIFY`` to support custom certificates and disabling certificate verification
to ``S3Boto3Storage`` (`#486`_, `#580`_)
- Add ``AWS_S3_PROXIES`` setting to ``S3Boto3Storage`` (`#583`_)
- Add a snazzy new logo. Big thanks to @reallinfo
**Bugfixes**
- Reset file read offset before passing to ``GoogleCloudStorage`` and ``AzureStorage`` (`#481`_, `#581`_, `#582`_)
- Fix various issues with multipart uploads in the S3 backends
(`#169`_, `#160`_, `#364`_, `#449`_, `#504`_, `#506`_, `#546`_)
- Fix ``S3Boto3Storage`` to stream down large files (also disallow `r+w` mode) (`#383`_, `#548`_)
- Fix ``SFTPStorageFile`` to align with the core ``File`` abstraction (`#487`_, `#568`_)
- Catch ``IOError`` in ``SFTPStorage.delete`` (`#568`_)
- ``AzureStorage``, ``GoogleCloudStorage``, ``S3Boto3Storage`` and ``S3BotoStorage`` now
respect ``max_length`` when ``file_overwrite = True`` (`#513`_, `#554`_)
- The S3 backends now consistently use ``compresslevel=9`` (the Python stdlib default)
for gzipped content (`#572`_, `#576`_)
- Improve error message of ``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)
******************
* You can now specify the backend you are using to install the necessary dependencies using
``extra_requires``. For example ``pip install django-storages[boto3]`` (`#417`_)
* Add additional content-type detection fallbacks (`#406`_, `#407`_)
* Add ``GS_LOCATION`` setting to specify subdirectory for ``GoogleCloudStorage`` (`#355`_)
* Add support for uploading large files to ``DropBoxStorage``, fix saving files (`#379`_, `#378`_, `#301`_)
* Drop support for Django 1.8 and Django 1.10 (and hence Python 3.3) (`#438`_)
* Implement ``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)
******************
* Fix Django 1.11 regression with gzipped content being saved twice
resulting in empty files (`#367`_, `#371`_, `#373`_)
* Fix the ``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)
******************
* Files uploaded with ``GoogleCloudStorage`` will now set their appropriate mimetype (`#320`_)
* Fix ``DropBoxStorage.url`` to work. (`#357`_)
* Fix ``S3Boto3Storage`` when ``AWS_PRELOAD_METADATA = True`` (`#366`_)
* Fix ``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)
******************
* Revert default ``AWS_S3_SIGNATURE_VERSION`` to V2 to restore backwards
compatability 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)
******************
* Fix regression in ``safe_join()`` to handle a trailing slash in an
intermediate path. (`#341`_)
* Fix regression in ``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)
******************
* Drop support for Django 1.9 (`e89db45`_)
* Fix regression in ``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)
******************
* **Breaking:** Remove backends deprecated in v1.5.1 (`#280`_)
* **Breaking:** ``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`_)
* **Breaking:** The ``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`_)
* **Breaking:** The default version value for ``AWS_S3_SIGNATURE_VERSION`` is now ``'s3v4'``. No changes should
be required (`#335`_)
* **Deprecation:** The undocumented ``gs.GSBotoStorage`` backend. See the new ``gcloud.GoogleCloudStorage``
or ``apache_libcloud.LibCloudStorage`` backends instead. (`#236`_)
* Add a new backend, ``gcloud.GoogleCloudStorage`` based on the ``google-cloud`` bindings. (`#236`_)
* Pass in the location constraint when auto creating a bucket in ``S3Boto3Storage`` (`#257`_, `#258`_)
* Add support for reading ``AWS_SESSION_TOKEN`` and ``AWS_SECURITY_TOKEN`` from the environment
to ``S3Boto3Storage`` and ``S3BotoStorage``. (`#283`_)
* Fix Boto3 non-ascii filenames on Python 2.7 (`#216`_, `#217`_)
* Fix ``collectstatic`` timezone handling in and add ``get_modified_time`` to ``S3BotoStorage`` (`#290`_)
* Add support for Django 1.11 (`#295`_)
* Add ``project`` keyword support to GCS in ``LibCloudStorage`` backend (`#269`_)
* Files that have a guessable encoding (e.g. gzip or compress) will be uploaded with that Content-Encoding in
the ``s3boto3`` backend (`#263`_, `#264`_)
* The Dropbox backend now properly translates backslashes in Windows paths into forward slashes (`e52a127`_)
* The S3 backends now permit colons in the keys (`#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)
******************
* Actually use ``SFTP_STORAGE_HOST`` in ``SFTPStorage`` backend (`#204`_)
* Fix ``S3Boto3Storage`` to avoid race conditions in a multi-threaded WSGI environment (`#238`_)
* Fix trying to localize a naive datetime when ``settings.USE_TZ`` is ``False`` in ``S3Boto3Storage.modified_time``.
(`#235`_, `#234`_)
* Fix automatic bucket creation in ``S3Boto3Storage`` when ``AWS_AUTO_CREATE_BUCKET`` is ``True`` (`#196`_)
* Improve the documentation for the S3 backends
.. _#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)
******************
* **Breaking:** Drop support for Django 1.7 (`#185`_)
* **Deprecation:** hashpath, image, overwrite, mogile, symlinkorcopy, database, mogile, couchdb.
See (`#202`_) to discuss maintenance going forward
* Use a fixed ``mtime`` argument for ``GzipFile`` in ``S3BotoStorage`` and ``S3Boto3Storage`` to ensure
a stable output for gzipped files
* Use ``.putfileobj`` instead of ``.put`` in ``S3Boto3Storage`` to use the transfer manager,
allowing files greater than 5GB to be put on S3 (`#194`_ , `#201`_)
* Update ``S3Boto3Storage`` for Django 1.10 (`#181`_) (``get_modified_time`` and ``get_accessed_time``)
* Fix bad kwarg name in ``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)
******************
* Add new backend ``S3Boto3Storage`` (`#179`_)
* Add a `strict` option to `utils.setting` (`#176`_)
* Tests, documentation, fixing ``.close`` for ``SFTPStorage`` (`#177`_)
* Tests, documentation, add `.readlines` for ``FTPStorage`` (`#175`_)
* Tests and documentation for ``DropBoxStorage`` (`#174`_)
* Fix ``MANIFEST.in`` to not ship ``.pyc`` files. (`#145`_)
* Enable CI testing of Python 3.5 and fix test failure from api change (`#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)
******************
* Files that have a guessable encoding (e.g. gzip or compress) will be uploaded with that Content-Encoding
in the ``s3boto`` backend. Compressable types such as ``application/javascript`` will still be gzipped.
PR `#122`_
* Fix ``DropBoxStorage.exists`` check and add ``DropBoxStorage.url`` (`#127`_)
* Add ``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)
****************
* This package is now released on PyPI as `django-storages`. Please update your requirements files to
`django-storages==1.4`.
1.3.2 (2016-01-26)
******************
* Fix memory leak from not closing underlying temp file in ``s3boto`` backend (`#106`_)
* Allow easily specifying a custom expiry time when generating a url for ``S3BotoStorage`` (`#96`_)
* Check for bucket existence when the empty path ('') is passed to ``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)
******************
* A few Azure Storage fixes [pass the content-type to Azure, handle chunked content, fix ``url``] (`#45`__)
* Add support for a Dropbox (``dropbox``) storage backend
* Various fixes to the ``apache_libcloud`` backend [return the number of bytes asked for by ``.read``, make ``.name`` non-private, don't
initialize to an empty ``BytesIO`` object] (`#55`_)
* Fix multi-part uploads in ``s3boto`` backend not respecting ``AWS_S3_ENCRYPTION`` (`#94`_)
* Automatically gzip svg files (`#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)
****************
* **Breaking:** Drop Support for Django 1.5 and Python 2.6
* **Breaking:** Remove previously deprecated mongodb backend
* **Breaking:** Remove previously deprecated ``parse_ts_extended`` from s3boto storage
* Add support for Django 1.8+ (`#36`__)
* Add ``AWS_S3_PROXY_HOST`` and ``AWS_S3_PROXY_PORT`` settings for s3boto backend (`#41`_)
* Fix Python3K compat issue in apache_libcloud (`#52`_)
* Fix Google Storage backend not respecting ``GS_IS_GZIPPED`` setting (`#51`__, `#60`_)
* Rename FTP ``_name`` attribute to ``name`` which is what the Django ``File`` api is expecting (`#70`_)
* Put ``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)
******************
* Variety of FTP backend fixes (fix ``exists``, add ``modified_time``, remove call to non-existent function) (`#26`_)
* Apparently the year changed to 2015
.. _#26: https://github.com/jschneier/django-storages/pull/26
1.2.2 (2015-01-28)
******************
* Remove always show all warnings filter (`#21`_)
* Release package as a wheel
* Avoid resource warning during install (`#20`__)
* Made ``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)
******************
* **Deprecation:** Issue warning about ``parse_ts_extended``
* **Deprecation:** mongodb backend - django-mongodb-engine now ships its own storage backend
* Fix ``storage.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)
****************
* **Breaking:** Remove legacy S3 storage (`#1`_)
* **Breaking:** Remove mosso files backend (`#2`_)
* Add text/javascript mimetype to S3BotoStorage gzip allowed defaults
* Add support for Django 1.7 migrations in S3BotoStorage and ApacheLibCloudStorage (`#5`_, `#8`_)
* Python3K (3.3+) now available for S3Boto backend (`#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)
******************
* Fix syntax for Python3 with pull-request `#91`_
* Support pushing content type from File object to GridFS with pull-request `#90`_
* Support passing a region to the libcloud driver with pull-request `#86`_
* Handle trailing slash paths fixes `#188`_ fixed by pull-request `#85`_
* Use a SpooledTemporaryFile to conserve memory in S3BotoFile pull-request `#69`_
* Guess content-type for S3BotoStorageFile the same way that _save() in S3BotoStorage does
* Pass headers and response_headers through from url to generate_url in S3BotoStorage pull-request `#65`_
* Added AWS_S3_HOST, AWS_S3_PORT and AWS_S3_USE_SSL settings to specify host, port and is_secure in pull-request `#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)
******************
* Fixes `#156`_ regarding date parsing, ValueError when running collectstatic
* Proper handling of boto dev version parsing
* Made SFTP URLs accessible, now uses settings.MEDIA_URL instead of sftp://
.. _#156: https://bitbucket.org/david/django-storages/issue/156/s3boto-backend-valueerror-time-data-thu-07
1.1.7 (2013-03-20)
******************
* Listing of huge buckets on S3 is now prevented by using the prefix argument to boto's list() method
* Initial support for Windows Azure Storage
* Switched to useing boto's parse_ts date parser getting last modified info when using S3boto backend
* Fixed key handling in S3boto and Google Storage backends
* Account for lack of multipart upload in Google Storage backend
* Fixed seek() issue when using AWS_IS_GZIPPED by darkness51 with pull-request `#50`_
* Improvements to S3BotoStorage and GSBotoStorage
.. _#50: https://bitbucket.org/david/django-storages/pull-request/50/
1.1.6 (2013-01-06)
******************
* Merged many changes from Jannis Leidel (mostly regarding gzipping)
* Fixed tests by Ian Lewis
* Added support for Google Cloud Storage backend by Jannis Leidel
* Updated license file by Dan Loewenherz, fixes `#133`_ with pull-request `#44`_
* Set Content-Type header for use in upload_part_from_file by Gerardo Curiel
* Pass the rewind parameter to Boto's set_contents_from_file method by Jannis Leidel with pull-request `#45`_
* Fix for FTPStorageFile close() method by Mathieu Comandon with pull-request `#43`_
* Minor refactoring by Oktay Sancak with pull-request `#48`_
* Ungzip on download based on Content-Encoding by Gavin Wahl with pull-request `#46`_
* Add support for S3 server-side encryption by Tobias McNulty with pull-request `#17`_
* Add an optional setting to the boto storage to produce protocol-relative URLs, fixes `#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)
******************
* Merged pull request `#36`_ from freakboy3742 Keith-Magee, improvements to Apache Libcloud backend and docs
* Merged pull request `#35`_ from atodorov, allows more granular S3 access settings
* Add support for SSL in Rackspace Cloudfiles backend
* Fixed the listdir() method in s3boto backend, fixes `#57`_
* Added base url tests for safe_join in s3boto backend
* Merged pull request `#20`_ from alanjds, fixed SuspiciousOperation warning if AWS_LOCATION ends with '/'
* Added FILE_BUFFER_SIZE setting to s3boto backend
* Merged pull request `#30`_ from pendletongp, resolves `#108`_, `#109`_ and `#110`_
* Updated the modified_time() method so that it doesn't require dateutil. fixes `#111`_
* Merged pull request `#16`_ from chamal, adds Apache Libcloud backend
* When preloading the S3 metadata make sure we reset the files key during saving to prevent stale metadata
* Merged pull request `#24`_ from tobias.mcnulty, fixes bug where s3boto backend returns modified_time in wrong time zone
* Fixed HashPathStorage.location to no longer use settings.MEDIA_ROOT
* Remove download_url from setup file so PyPI dist is used
.. _#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)
******************
* Added PendingDeprecationWarning for mosso backend
* Merged pull request `#13`_ from marcoala, adds ``SFTP_KNOWN_HOST_FILE`` setting to SFTP storage backend
* Merged pull request `#12`_ from ryankask, fixes HashPathStorage tests that delete remote media
* Merged pull request `#10`_ from key, adds support for django-mongodb-engine 0.4.0 or later, fixes GridFS file deletion bug
* Fixed S3BotoStorage performance problem calling modified_time()
* Added deprecation warning for s3 backend, refs `#40`_
* Fixed CLOUDFILES_CONNECTION_KWARGS import error, fixes `#78`_
* Switched to sphinx documentation, set official docs up on https://django-storages.readthedocs.io/
* HashPathStorage uses self.exists now, fixes `#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)
******************
* Created this lovely change log
* Fixed `#89`_: broken StringIO import in CloudFiles backend
* Merged `pull 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