David Santiago
David Santiago I'm spend my life juggling between iTerm & Azure portal. I am passionate about infrastructure and automation.

Django — Using Azure blob storage to handle static & media assets — from scratch

Django — Using Azure blob storage to handle static & media assets — from scratch

This post was originally published on Medium.

In this tutorial, we will see how to use the Azure Blob service to handle static assets & media assets (user uploaded files) with Django.

Fundations

I need to create a Resource Group, Storage Account and two containers. I will use the following naming convention:

  • Resource group name: DemoDjangoBlob
  • Storage Account name: djangoaccountstorage
  • Media container name: media
  • Static container name: static

Resources creation using Azure CLI

1
2
3
4
5
6
7
8
9
10
# Create resource group named DemoDjangoBlob
$ az group create -l westeurope -n DemoDjangoBlob
# Create storage account named djangoaccountstorage
$ az storage account create -n djangoaccountstorage -g DemoDjangoBlob -l westeurope --sku Standard_LRS --https-only true
# (optional) Update storage account to V2
$ az storage account update -n djangoaccountstorage -g DemoDjangoBlob --set kind=StorageV2
# Create the "media" container_  
$ az storage container create -n media --account-name djangoaccountstorage --public-access blob
# Create the "static" container 
$ az storage container create -n static --account-name djangoaccountstorage --public-access blob

Resources creation using Azure Portal

Select Subscription and display Resource group list. Click on “Create Resource group”.

rg-creation

Click on “Create”, go to the resource group and Click on “Create resources”.

Searchstorage account” and Click on “Create”. Configure the Storage Account as following:

sa-creation

EnableSecure transfer required” in Advanced tab and Create the resource.

Go to the resource on “Blob service” item menu. Create static and media containers with “Blob” public access level :

containers-access-level

It is done. We will need to manage Storage Account Keys later, they are located in “Access Keys” item menu.

Install and configure Django

The easiest way is to install everything using pipenv :

1
2
3
4
5
6
7
8
# Basic Django installation_  
$ mkdir demo-django-azure_blob  
$ cd demo-django-azure_blob/  
$ pipenv install django  
$ pipenv install django-storages[azure]  
$ pipenv shell  
(demo-django-azure_blob) $ django-admin.py startproject backend .  
(demo-django-azure_blob) $ python manage.py migrate

Add storages to INSTALLED_APPS in settings.py module:

1
2
3
4
5
6
7
8
9
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'storages',
]

Then, Add the following lines at the end of settings.py module :

1
2
3
4
5
6
7
8
9
10
DEFAULT_FILE_STORAGE = 'backend.custom_azure.AzureMediaStorage'
STATICFILES_STORAGE = 'backend.custom_azure.AzureStaticStorage'

STATIC_LOCATION = "static"
MEDIA_LOCATION = "media"

AZURE_ACCOUNT_NAME = "djangoaccountstorage"
AZURE_CUSTOM_DOMAIN = f'{AZURE_ACCOUNT_NAME}.blob.core.windows.net'
STATIC_URL = f'https://{AZURE_CUSTOM_DOMAIN}/{STATIC_LOCATION}/'
MEDIA_URL = f'https://{AZURE_CUSTOM_DOMAIN}/{MEDIA_LOCATION}/'

AZURE_ACCOUNT_NAME must be replaced by the storage account name.

Finally, create a custom_azure.py file in backend/ folder and replace account_name and account_key values:

1
2
3
4
5
6
7
8
9
10
11
12
13
from storages.backends.azure_storage import AzureStorage

class AzureMediaStorage(AzureStorage):
    account_name = 'djangoaccountstorage' # <storage_account_name>
    account_key = 'your_key_here' # <storage_account_key>
    azure_container = 'media'
    expiration_secs = None

class AzureStaticStorage(AzureStorage):
    account_name = 'djangoaccountstorage' # <storage_account_name>
    account_key = 'your_key_here' # <storage_account_key>
    azure_container = 'static'
    expiration_secs = None

Get storage account key with Azure CLI :

1
$ az storage account keys list -n djangoaccountstorage -g DemoDjangoBlob

It is almost finished. Azure resources and Django are ready, let’s migrate static & media files now.

Migrate static files

collectstatic command will copy files to remote location now.

1
2
3
4
5
6
7
(demo-django-blob) $ python manage.py collectstatic
You have requested to collect static files at the destination
location as specified in your settings.
This will overwrite existing files!
Are you sure you want to do this?
Type 'yes' to continue, or 'no' to cancel: yes
119 static files copied

119 static files were copied but I have an “empty” project. In fact, Django Admin static files (css, fonts, js and img) were copied.

Test it

Run the local server without static files:

1
(demo-django-blob) $ python manage.py runserver --nostatic

Navigate to http://127.0.0.1:8000/admin/login/?next=/admin/

We have the following Django administration page :

django-admin

Check source code:

page-source

Conclusions

Using Azure blob service with Django is pretty easy thanks to django-storages library. Moreover, features like Azure CDN will come soon 😃.

Next steps can be :

  • Store account_name and account_key inside environment variables.
  • Deal with Cross-Origin Ressource Sharing supported by Azure Storage Services

Hope this tutorial was helpful. Feel free to leave me a feedback 😏.

PS: This tutorial was largely inspired by the tutorial from Vitor Freitas : How to Setup Amazon S3 in a Django Project.

comments powered by Disqus