DEV Community

Cover image for Makefile for your Django project
Yevhen Bondar for Daiquiri Team

Posted on

Makefile for your Django project

During the development process, you often need to run some commands in your terminal: create migrations, run tests, linters, etc. Usually, you execute these commands regularly.

It's helpful to have shortcuts for such commands. And even better to share them among other developers on the project. For this goal, I use Makefile. Here is the list of useful commands for a Django project.

Installing dependencies

I'm not a big fan of Poetry. It has some problems with Dependabot and doesn't play with Renovate at all. I use pip-tools with separate requirements.in and requirements-dev.in for local and prod environments.

pip-install-dev:
    pip install --upgrade pip pip-tools
    pip-sync requirements.txt requirements-dev.txt

pip-install:
    pip install --upgrade pip pip-tools
    pip-sync requirements.txt

pip-update:
    pip install --upgrade pip pip-tools
    pip-compile requirements.in
    pip-compile requirements-dev.in
    pip-sync requirements.txt requirements-dev.txt
Enter fullscreen mode Exit fullscreen mode

Commands:

  • pip-install-dev: Installs all requirements, including local. It is the main command for installing the project's dependencies, so I put this command at the top.
  • pip-install - I don't use this command often, but it could be helpful to run your code with production dependencies only.
  • pip-update Updates your requirements.txt and requirements-dev.txt after you add a new package to the requirements.in or requirements-dev.in.

Running the project

server:
    python manage.py migrate && python manage.py runserver

worker:
    python -m celery -A project_name worker --loglevel info

beat:
    python -m celery -A project_name beat --loglevel info
Enter fullscreen mode Exit fullscreen mode

That is an obvious one. The commands to run local web server and Celery. Also, I like to apply new migrations automatically when I run the server.

Running linters

lint:
    flake8 palyanytsya
    mypy palyanytsya

black:
    python -m black palyanytsya

cleanimports:
    isort .
    autoflake -r -i --remove-all-unused-imports --ignore-init-module-imports project_name

clean-lint: cleanimports black lint

checkmigrations:
    python manage.py makemigrations --check --no-input --dry-run
Enter fullscreen mode Exit fullscreen mode

Commands:

  • lint: Runs flake8 linter and mypy type checker.
  • black: Automatic code formatting with Black.
  • cleanimports: runs isort and removes unused imports with Autoflake. Be sure to set up profile=black in isort settings to avoid conflicts with Black.
  • clean-lint: run all the stuff above. You can run this command before committing to formatting your code properly.
  • checkmigrations: prevents you from committing model changes without migrations. Really cool stuff!

Also, I use make lint && make checkmigrations in the CI pipeline and in the git pre-commit hook. You can also create a command for setting up such a hook:

install-hooks:
    echo "make lint && make checkmigrations" > .git/hooks/pre-commit && chmod 777 .git/hooks/pre-commit
Enter fullscreen mode Exit fullscreen mode

Running tests

test:
    pytest -n 4 -x
Enter fullscreen mode Exit fullscreen mode

Runs pytest in multiprocess mode using pytest-xdist.

Compiling messages

messages:
    python manage.py makemessages --all --ignore=venv --extension html,py
    python manage.py translate_messages -s en -l uk -l es -u
    python manage.py compilemessages --ignore venv
Enter fullscreen mode Exit fullscreen mode

Collects all string literals for translation. Also, I use Django Autotranslate to translate phrases using Google Translate automatically.

The end

As long as the project goes on, new local commands appear. Maybe, you need to shell into the dev server to run some python code. Or download a fresh database dump (without sensitive data) for local bug reproducing. It's better to keep this knowledge in the codebase, not in your head. Also, you won't need to explain how to do exactly the same operation to your colleagues.

For more complex tasks, you can even create a shell script and call it from Makefile. So, it would be easier to find this new command for other devs.

Top comments (0)