I’ll present you a Django layout which allow to ship your project (not app) as a Python package. Your users will be able to install it with pip for example.
This template is available as a Cookiecutter template. But I’ll remove every references, because this paper is mainly written to present you a Django project layout. Maybe I’ll do another post about Cookiecutter later.
My first need is to be able to install my Django project via pip install my-awesome-app
and access it via my-awesome-app
entry point
without losing manage.py
flexibility.
The first reference for this template is Sentry project. I’m really appreciative of how this project is nicely built by nice people.
Let’s describe how it works!
Layout
This is a little description of my typical layout for every new Django project I build.
In order to have a pip installable project we need to have a setup.py
like every Python package.
You’ll notive that we don’t need requirements.txt
at all. Hooray! All your dependencies will be organized in setup.py
.
No more requirements-[dev|test].txt
files, setuptools extras_require
option will do the trick.
You’ll probably need a core
app (line 15) and many other apps (line 12). Another special directory is runner
where your
command line entry points will be stored.
Django community have various ways to organize settings, feel free to use your own but I prefer to have a base.py
(line 25) settings file and another local.py
which will be imported in settings/__init__.py
.
It’s always a good thing to give users local.dist.py
(line 26) or production.dist.py
example files, as long as Django settings number always tend to grow.
Always try to put a little description below every settings that can be complex. But don’t try to describe all them all if it seems easy to understand.
This kind of documentation can be difficult to keep up-to-date.
Install process
A developper install process will be something like that:
- Cloning repository
- Build virtualenv
pip install -e .[dev,test]
- Coding.
A production deployment for a PyPI published project will be:
pip install my-awesome-project
- Run command line:
my-awesome-project --help
Let’s take a quick look at setup.py
:
This extra_require
option is pretty useful. You can have a production
one which contains for example Gunicorn or Psycopg, etc…
Where is my manage.py
?
First of all, don’t panic! You still have django-admin
command line tool which is very similar to manage.py
.
Instead of python manage.py shell
, you can do:
DJANGO_SETTINGS_MODULE=my_awesome_project.settings django-admin shell
Ok, it’s very verbose. This is why this template give you another approach with runner
which use click library.
Main goal is to be able to do something like:
my-awesome-project django shell
Then every Django commands will be accessible. You can take a look at how it works here.
This is a dead simple example of a custom command which return Django version.
End
I know every Django or project layouts can be personnal but here, I want to show you how to ship a Django project in a professional way.
You can retrieve this template here.
Feel free to contact me for any questions, leave issue on Github.
In further posts I’ll speak about: “How to store package metadata”, “How to trash your unmaintainable fixtures” and more tools like bumpversion and docker-compose.