summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorPavel Shpilev <pavel.shpilev@medibank.com.au>2014-10-15 18:42:06 +1100
committerTim Graham <timograham@gmail.com>2015-01-12 09:09:18 -0500
commita7c256cb5491bf2a77abdff01638239db5bfd9d5 (patch)
tree3b3cd98b0f2f42efd989ae9dd9ab3dba473d972a /docs
parentb5c1a85b50c709770b8e98aeecfeb8e81ca29dcf (diff)
Fixed #9893 -- Allowed using a field's max_length in the Storage.
Diffstat (limited to 'docs')
-rw-r--r--docs/howto/custom-file-storage.txt20
-rw-r--r--docs/internals/deprecation.txt4
-rw-r--r--docs/ref/files/storage.txt20
-rw-r--r--docs/releases/1.8.txt21
4 files changed, 55 insertions, 10 deletions
diff --git a/docs/howto/custom-file-storage.txt b/docs/howto/custom-file-storage.txt
index 9b217b8031..3d2c96e2bd 100644
--- a/docs/howto/custom-file-storage.txt
+++ b/docs/howto/custom-file-storage.txt
@@ -50,7 +50,7 @@ typically have to be overridden:
* :meth:`Storage.size`
* :meth:`Storage.url`
-Note however that not all these methods are required and may be deliberately
+Note however that not all these methods are required and may be deliberately
omitted. As it happens, it is possible to leave each method unimplemented and
still have a working Storage.
@@ -87,7 +87,6 @@ instead).
.. method:: get_valid_name(name)
-
Returns a filename suitable for use with the underlying storage system. The
``name`` argument passed to this method is the original filename sent to the
server, after having any path information removed. Override this to customize
@@ -96,21 +95,28 @@ how non-standard characters are converted to safe filenames.
The code provided on ``Storage`` retains only alpha-numeric characters, periods
and underscores from the original filename, removing everything else.
-.. method:: get_available_name(name)
+.. method:: get_available_name(name, max_length=None)
Returns a filename that is available in the storage mechanism, possibly taking
the provided filename into account. The ``name`` argument passed to this method
will have already cleaned to a filename valid for the storage system, according
to the ``get_valid_name()`` method described above.
-.. versionchanged:: 1.7
+The length of the filename will not exceed ``max_length``, if provided. If a
+free unique filename cannot be found, a :exc:`SuspiciousFileOperation
+<django.core.exceptions.SuspiciousOperation>` exception is raised.
+
+If a file with ``name`` already exists, an underscore plus a random 7 character
+alphanumeric string is appended to the filename before the extension.
- If a file with ``name`` already exists, an underscore plus a random 7
- character alphanumeric string is appended to the filename before the
- extension.
+.. versionchanged:: 1.7
Previously, an underscore followed by a number (e.g. ``"_1"``, ``"_2"``,
etc.) was appended to the filename until an available name in the destination
directory was found. A malicious user could exploit this deterministic
algorithm to create a denial-of-service attack. This change was also made
in Django 1.6.6, 1.5.9, and 1.4.14.
+
+.. versionchanged:: 1.8
+
+ The ``max_length`` argument was added.
diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt
index 345202545e..fe392cff97 100644
--- a/docs/internals/deprecation.txt
+++ b/docs/internals/deprecation.txt
@@ -143,6 +143,10 @@ details on these changes.
* Support for the ``=`` comparison operator in the ``if`` template tag will be
removed.
+* The backwards compatibility shims to allow ``Storage.get_available_name()``
+ and ``Storage.save()`` to be defined without a ``max_length`` argument will
+ be removed.
+
.. _deprecation-removed-in-1.9:
1.9
diff --git a/docs/ref/files/storage.txt b/docs/ref/files/storage.txt
index a16b6b6c9d..88da416dcf 100644
--- a/docs/ref/files/storage.txt
+++ b/docs/ref/files/storage.txt
@@ -114,12 +114,17 @@ The Storage Class
in the storage system, or ``False`` if the name is available for a new
file.
- .. method:: get_available_name(name)
+ .. method:: get_available_name(name, max_length=None)
Returns a filename based on the ``name`` parameter that's free and
available for new content to be written to on the target storage
system.
+ The length of the filename will not exceed ``max_length``, if provided.
+ If a free unique filename cannot be found, a
+ :exc:`SuspiciousFileOperation
+ <django.core.exceptions.SuspiciousOperation>` exception will be raised.
+
If a file with ``name`` already exists, an underscore plus a random
7 character alphanumeric string is appended to the filename before
the extension.
@@ -133,6 +138,10 @@ The Storage Class
attack. This change was also made in Django 1.6.6, 1.5.9, and
1.4.14.
+ .. versionchanged:: 1.8
+
+ The ``max_length`` argument was added.
+
.. method:: get_valid_name(name)
Returns a filename based on the ``name`` parameter that's suitable
@@ -165,17 +174,24 @@ The Storage Class
standard ``open()``. For storage systems that aren't accessible from
the local filesystem, this will raise ``NotImplementedError`` instead.
- .. method:: save(name, content)
+ .. method:: save(name, content, max_length=None)
Saves a new file using the storage system, preferably with the name
specified. If there already exists a file with this name ``name``, the
storage system may modify the filename as necessary to get a unique
name. The actual name of the stored file will be returned.
+ The ``max_length`` argument is passed along to
+ :meth:`get_available_name`.
+
The ``content`` argument must be an instance of
:class:`django.core.files.File` or of a subclass of
:class:`~django.core.files.File`.
+ .. versionchanged:: 1.8
+
+ The ``max_length`` argument was added.
+
.. method:: size(name)
Returns the total size, in bytes, of the file referenced by ``name``.
diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt
index c4e4e34894..122064971c 100644
--- a/docs/releases/1.8.txt
+++ b/docs/releases/1.8.txt
@@ -317,7 +317,15 @@ Email
File Storage
^^^^^^^^^^^^
-* ...
+* :meth:`Storage.get_available_name()
+ <django.core.files.storage.Storage.get_available_name>` and
+ :meth:`Storage.save() <django.core.files.storage.Storage.save>`
+ now take a ``max_length`` argument to implement storage-level maximum
+ filename length constraints. Filenames exceeding this argument will get
+ truncated. This prevents a database error when appending a unique suffix to a
+ long filename that already exists on the storage. See the :ref:`deprecation
+ note <storage-max-length-update>` about adding this argument to your custom
+ storage classes.
File Uploads
^^^^^^^^^^^^
@@ -1432,6 +1440,17 @@ loader that inherits ``BaseLoader``, you must inherit ``Loader`` instead.
Private API ``django.test.utils.TestTemplateLoader`` is deprecated in favor of
``django.template.loaders.locmem.Loader``.
+.. _storage-max-length-update:
+
+Support for the ``max_length`` argument on custom ``Storage`` classes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``Storage`` subclasses should add ``max_length=None`` as a parameter to
+:meth:`~django.core.files.storage.Storage.get_available_name` and/or
+:meth:`~django.core.files.storage.Storage.save` if they override either method.
+Support for storages that do not accept this argument will be removed in
+Django 2.0.
+
``qn`` replaced by ``compiler``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~