Django Shorts : Uploading images to cloud storage

Kartik Nema
4 min readJan 26, 2023

--

Cloud Storage is increasingly becoming popular over traditional solutions. AWS S3, Azure Storage and other such platforms are widely used. In this blog we’ll see how we can upload media files to cloud storage. We’ll use Firebase Storage for this purpose, as it is free and requires minimal setup.

Step 1 : Create a Firebase Project

First log in to firebase console https://console.firebase.google.com/u/0/ using your google credentials. Select add Project and provide a name for your project, once that is done you can click through defaults for the remaining fields.

Step 2 : Add an App

Select the project just created, Click the option to add an App and add a Web App. Provide a name and register it. Once that is done you’ll get some started code. Which will look similar to this

// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAnalytics } from "firebase/analytics";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: "<>",
authDomain: "<>",
projectId: "<>",
storageBucket: "<>",
messagingSenderId: "<>",
appId: "<>",
measurementId: "<>"
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);

We are interested in the firebaseConfig dictionary, so copy it and keep it for future use.

Step 3 : Adding Firebase to our Django Project

To add firebase to django project we’ll use a helper module called pyrebase.

pip install pyrebase

If the above command results in errors then try

pip install pyrebase4

Next we’ll upload an image to firebase storage. In this case we’ll just upload an image from our local computer by hard coding it’s path. However a better strategy would be to allow the user to upload a file via form input, and store it in media directory following which we can upload it to firebase storage. However in this piece we are seeing the basic method.

Step 4 : Uploading the image

The setup will be minimal. First create the Django project and an app.

django-admin startproject firebase_upload
cd firebase_upload
python manage.py startapp upload_image

In the project’s urls.py

from upload_image import views
urlpatterns += [path(''), views.upload_to_firebase, name='upload']

In the app’s urls.py

from django.http.response import HttpResponse
def upload_to_firebase(req):
upload_helper()
return HttpResponse('Upload Completed')

def upload_helper():
# Use the credentials obtained during project setup on Firebase, leave
# databaseUrl as "", since we aren't using Firebase provided database
# services for our app

firebase = pyrebase.initialize_app({
"apiKey": <>,
"authDomain": <>,
"projectId": <>,
"storageBucket": <>,
"messagingSenderId": <>,
"appId": <>,
"measurementId": <>,
"databaseURL": ""
})
storage = firebase.storage()

file_path = <> # specify absolute path to any image on your local computer
image_name = 'random_image_1'

storage.child(f"images/{image_name}.jpg").put(full_path)

Step 5: Change upload rules in Firebase Storage

By default firebase storage only allows access if the user is authenticated. To bypass it go to Storage tab in your firebase app and replace the existing rule with this, and then publish the rules.

rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: true;
}
}
}

Once all this is done try uploading the image to firebase by starting the server.

Enhancements

Hide the secrets

Move your credentials to an .env file in your app’s directory.

API_KEY=<>
AUTH_DOMAIN=<>
PROJECT_ID=<>
STORAGE_BUCKET=<>
MESSAGING_SENDER_ID=<>
APP_ID=<>
MEASUREMENT_ID=<>

Next, install the environ module

pip install django-environ

import the module in views.py and make the following changes

import environ

def upload_helper():
# Use the credentials obtained during project setup on Firebase, leave
# databaseUrl as "", since we aren't using Firebase provided database
# services for our app

env = environ.Env()
environ.Env.read_env()

firebase = pyrebase.initialize_app({
"apiKey": env('API_KEY'),
"authDomain": env('AUTH_DOMAIN'),
"projectId": env('PROJECT_ID'),
"storageBucket": env('STORAGE_BUCKET'),
"messagingSenderId": env('MESSAGING_SENDER_ID'),
"appId": env('APP_ID'),
"measurementId": env('MEASUREMENT_ID'),
"databaseURL": ""
})
storage = firebase.storage()

file_path = <> # specify absolute path to any image on your local computer
image_name = 'random_image_2'

storage.child(f"images/{image_name}.jpg").put(full_path)

Don’t forget to add .env to your project’s .gitignore

Enhancements

Move the upload task to antoher thread

Since we don’t want to block the main thread it makes sense to create another thread focussed solely on the upload task.

In views.py make the following changes, first replace the call to upload_helper.

def upload_to_firebase(req):
thread_helper()
return HttpResponse('Upload Completed')

Create the thread_helper function which will actually invoke the upload_helper on a separate thread.

import threading
def thread_helper():
thread_task = threading.Thread(target=upload_helper)
thread_task.setDaemon(True)
thread_task.start()

No changes are needed in upload_helper itself. This will allow you to do the upload task in the background without blocking the main/UI thread.

--

--