Our goal when packaging up a Django application, is that we can use it as part of an existing application, or we can run it by itself in a standalone mode. To this end, I have over time, started to package my django applications in the following way. You can see diffs of all the commits in the example-django repository.
Start with a Makefile and setup files
Instead of using tools like Poetry and Pipenv , I find it easier to just create a basic Makefile to use as the entrypoint.
APP_BIN := .venv/bin/example-django
PIP_BIN := .venv/bin/pip
.DEFAULT: test
.PHONY: test
test: ${APP_BIN}
${APP_BIN} test -v 2
$(PIP_BIN):
python3 -m venv .venv
${APP_BIN}: $(PIP_BIN)
${PIP_BIN} install -r docker/requirements.txt
${PIP_BIN} install -e .[dev,standalone]
We then create a stub for setup.py
for our install trigger
from setuptools import setup
setup()
And then some basic values for our setup.cfg
[metadata]
name = example-django
version = 0.0.1
[options]
packages = find:
install_requires =
Django>=2.0
[options.entry_points]
console_scripts =
example-django = example.standalone.manage:main
And we will populate docker/requirements.txt
with a stub. In a full application, we would also use this for some of our Docker specific requirements.
-i https://pypi.org/simple
-e .
with this setup, we can run make
to create our initial environment. It will throw an error because it can not find some files, but it will create our default virtual environment.
Creating and configuring our Project
For my Django projects, I like to have a basic Django application, but also ship a standalone configuration that can be used for test cases. To start will will create a new app example
and a new project standalone
to populate those files.
.venv/bin/django-admin startapp example
.venv/bin/django-admin startproject standalone
git add example
git add standalone
git commit -m "Initial django-admin setup"
Next we want to move our standalone app into the correct place.
git mv standalone/* example
git mv example/manage.py example/standalone
We want to edit example/standalone/__init__.py
with our default environment settings
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example.standalone.settings")
and then we can remove the os.environ
line from our asgi.py
, manage.py
, and wsgi.py
. We need to update settings.py
to update our URL config
ROOT_URLCONF = 'example.standalone.urls'
You can see diffs of all the commits in the example-django repository.