A custom storage system for Django using Windows Azure Storage backend.
Be aware Azure file names have some extra restrictions. They can’t:
- end with a dot (
.) or slash (
- contain more than 256 slashes (
- be longer than 1024 characters
This is usually not an issue, since some file-systems won’t
allow this anyway.
to get the
max_length allowed. This is useful
for form inputs. It usually returns
1024 - len(azure_location_setting).
to clean up file names when migrating to Azure.
Gzipping for static files must be done through Azure CDN.
Install Azure SDK:
pip install django-storages[azure]
Private VS Public Access¶
AzureStorage allows a single container. The container may have either
public access or private access. When dealing with a private container, the
AZURE_URL_EXPIRATION_SECS must be set to get temporary URLs.
A common setup is having private media files and public static files, since public files allow for better caching (i.e: no query-string within the URL).
One way to support this is having two backends, a regular
with the private container and expiration setting set, and a custom
backend (i.e: a subclass of
AzureStorage) for the public container.
# file: ./custom_storage/custom_azure.py class PublicAzureStorage(AzureStorage): account_name = 'myaccount' account_key = 'mykey' azure_container = 'mypublic_container' expiration_secs = None
Then on settings set:
DEFAULT_FILE_STORAGE = 'storages.backends.azure_storage.AzureStorage' STATICFILES_STORAGE = 'custom_storage.custom_azure.PublicAzureStorage'
The following settings should be set within the standard django configuration file, usually settings.py.
Set the default storage (i.e: for media files) and the static storage (i.e: fo static files) to use the azure backend:
DEFAULT_FILE_STORAGE = 'storages.backends.azure_storage.AzureStorage' STATICFILES_STORAGE = 'storages.backends.azure_storage.AzureStorage'
The following settings are available:
This setting is the Windows Azure Storage Account name, which in many cases is also the first part of the url for instance: http://azure_account_name.blob.core.windows.net/ would mean:AZURE_ACCOUNT_NAME = "azure_account_name"
This is the private key that gives Django access to the Windows Azure Account.
This is where the files uploaded through Django will be uploaded. The container must be already created, since the storage system will not attempt to create it.
Set a secure connection (HTTPS), otherwise it makes an insecure connection (HTTP). Default is
Number of connections to make when uploading a single file. Default is
Global connection timeout in seconds. Default is
Maximum memory used by a downloaded file before dumping it to disk. Unit is in bytes. Default is
Seconds before a URL expires, set to
Noneto never expire it. Be aware the container must have public read permissions in order to access a URL without expiration date. Default is
Overwrite an existing file when it has the same name as the file being uploaded. Otherwise, rename it. Default is
Default location for the uploaded files. This is a path that gets prepended to every file name.
Whether to use the emulator (i.e Azurite). Defaults to False.
The host base component of the url, minus the account name. Defaults to Azure (
core.windows.net). Override this to use the China cloud (
The custom domain to use. This can be set in the Azure Portal. For example,
It may contain a
host:portwhen using the emulator (
AZURE_EMULATED_MODE = True).
If specified, this will override all other parameters. See http://azure.microsoft.com/en-us/documentation/articles/storage-configure-connection-string/ for the connection string format.
This is similar to
AZURE_CONNECTION_STRING, but it’s used when generating the file’s URL. A custom domain or CDN may be specified here instead of within
AZURE_CONNECTION_STRING. Defaults to
A token credential used to authenticate HTTPS requests. The token value should be updated before its expiration.
A variable to set the Cache-Control HTTP response header. E.g.
AZURE_CACHE_CONTROL = "public,max-age=31536000,immutable"
Use this to set content settings on all objects. To set these on a per-object basis, subclass the backend and override
This is a Python
dictand the possible parameters are: