Django Framework has great out-of-the-box features that when used wisely can become powerful allies to create quick scalable solutions with less code. The Sites Framework is one of these great hidden gems, especially if you are trying to create a solution that handles multiple websites on the same application, such as White Label platforms.
In this tutorial I will show you how Django can make your life much easier for creating a white label using the sites framework. But first things first: what is a white label application?
In short, it is a solution or product that can be customized by easily inserting a new brand and still make it look like it was tailor-made.
During the tutorial, we will create a white label for an e-commerce website. The structure consists of multiple stores, each one with its own domain. All with the same code base.
If you are already familiar with Django you can skip the “Setup the project” part of this tutorial. If not, I will show you how to create a basic structure, so you can test our new white label with it. Let’s start it!
Setup the project
First, let’s structure our project by creating a virtual environment and installing Django.
# Create the site folder
mkdir -p white_label_tutorial/src/templates
cd white_label_tutorial/
# Create and activate the virtual env
python3 -m venv venv
source venv/bin/activate
# Install django and create our app
cd src/
pip install django
django-admin startproject app .
python manage.py startapp store
Don’t forget to add our app and template directory to the app/settings.py file.
from django.contrib import admin
from .models import Store, Product
admin.site.register(Store)
admin.site.register(Product)
Great! To see our progress so far, create a super user
python manage.py createsuperuser
and start the development server.
python manage.py runserver
You can login with your new user and see our templates at the Django admin page:
http://localhost:8000/admin
You can now create stores and products using the Django admin website.
Now, let’s create a view, a template and the url to show the data outside Django admin. Change the following files:
from django.views.generic.list import ListView
from .models import Product
class ProductListView(ListView):
model = Product
context_object_name = 'products'
app/urls.py
from store import views
urlpatterns = [
…,
path("", views.ProductListView.as_view(), name="product-list"),
]
Let’s add the relationship between website and Store model, so each store will have its own Site model.
from django.contrib.sites.models import Site
from django.db import models
class Store(models.Model):
name = models.CharField(max_length=255)
site = models.OneToOneField(Site, related_name="store", on_delete=models.CASCADE, null=True)
def __str__(self):
return self.name
Now when we access admin we will see a new Site model.
By running the migrations, Django already creates a first example.com site, but we are still able to access our app through the old localhost address.
We will add a new middleware that will only allow registered sites to access our application.
Before that, change the site domain added by Django exemple.com to localhost.com, so our application will continue to work locally. Add a new site myecommerce.com’ to be possible to test the application with a different domain, I will show how to test it locally. The new Site admin should look like this:
This middleware adds in every request a new site attribute.
For everything to work we need to update the ALLOWED_HOSTS in app/settings.py. For testing purpose you can use:
ALLOWED_HOSTS = ['*',]
It will accept requests from every host, but it is not a good practice.
We recommend using a lib to handle environment variables for you, so you don’t need to change the settings file and just change the environment variable. Read more about environment variables here.
To test our application with different domains let’s add a new record to the file etc/hosts (for UNIX-like systems):
127.0.0.1 myecommerce.com
127.0.0.1 localhost.com
Now with the server running we will access the admin interface and link the site we created to our store.
You can now access our site either through localhost.com or myecommerce.com.
We will change our template to show the name of the store that belongs to that site, so just above our div container in templates/store/product_list.html add the following code:
Going to myecommerce.com:8000/ you should see the store name linked to that site.
Finally we will show only the products for that store, so let’s overwrite the get_context_data method on the ProductListView class on store/views.py file.
This way, every site accessed will only show products filtered for a store associated with the respective domain.
Quick and easy. We set up a white label application using Django’s own tools. I hope you enjoyed this tutorial. The source code is on GITHUB LINK, if you have questions or suggestions feel free to ping me on matheusfernandes@ckl.io