Use Emacs as a Django IDE on Debian

GNU Emacs is one of the most powerful text editors that has ever been created but it is like an old dog that cannot easily learn new tricks. But here we try to tame this wild animal by adding some extra packages and making it ready to start developing Django projects.

We assume that we are running Debian 10 and have also superuser access. The same procedure would also be applicable to other GNU/Linux distributions especially Ubuntu. Also, as I prefer to install packages from the official Debian repos, instead of PyPI, then expect to install system-wide packages.

Installing prerequisites

$ sudo apt install emacs elpa-elpy python3-django python-django-doc elpa-flycheck elpa-pip-requirements elpa-gitlab-ci-mode python3-autopep8 python3-pip python3-venv black elpa-magit elpa-markdown-mode markdown elpa-web-mode jupyter-console elpa-aggressive-indent elpa-diff-hl elpa-solarized-theme
  • emacs: emacs26 version of GNU Emacs
  • elpa-elpy: a very powerful Python IDE for GNU Emacs with lots of cool features
  • python3-django: High-level Python web development framework. On Debian 10 we have the LTS version which is currently 2.2
  • python-django-doc: documentation accessible from file:///usr/share/doc/python-django-doc/html/index.html
  • elpa-flycheck: syntax checker
  • elpa-pip-requirements: syntax highlighting for PIP requirements
  • elpa-gitlab-ci-mode: Emacs mode for editing GitLab CI files
  • python3-autopep8: formats Python code to conform to PEP 8
  • python3-pip: Python package installer. PIP is not installed by default on GNU/Linux distributions
  • python3-venv: creating virtual environments
  • black: Python code formatter
  • elpa-magit: the most powerful git client ever existed.
  • elpa-markdown-mode: mode for editing Markdown-formatted text
  • markdown: we need to install it to be able to view and export markdown from within GNU Emacs
  • elpa-web-mode: major emacs mode for editing web templates, here Django Templates
  • jupyter-console: Jupyter terminal client.
  • elpa-aggressive-ident: Emacs minor mode that reindents code after every change
  • elpa-diff-hl: highlight uncommitted changes using VC
  • elpa-solarized-theme: port of Solarized theme to Emacs

Now that we have installed the necessary packages we are ready to config GNU Emacs. Add the following text to your GNU Emacs configuration file, e.g.: ~/.emacs

;; load theme
;; ===========
(load-theme 'solarized-light)
;; ------

;; yasnippet
;; ========
(require 'yasnippet)
(yas-global-mode 1)
;; --------

;; Enable global company mode
;; ==========================
(require 'company)
(add-hook 'after-init-hook 'global-company-mode)
(setq company-idle-delay 1)
(setq company-minimum-prefix-length 1)
;; ---------------------------

;; magit
;; ======
(setq magit-clone-set-remote.pushDefault t)
(global-set-key (kbd "C-x g") 'magit-status)
;; ------

;; elpy; emacs python development environment
;; ==========================================
(setq python-shell-interpreter "jupyter"
      python-shell-interpreter-args "console --simple-prompt"
      python-shell-prompt-detect-failure-warning nil)
(add-to-list 'python-shell-completion-native-disabled-interpreters
;; --------------------------------------------

;; new line at the end of the file
;; ==================================
(setq require-final-newline t)

;; show full path of the file in the frame title
;; =============================================
(setq frame-title-format
      '("" invocation-name ": "
         (if buffer-file-name
             (abbreviate-file-name buffer-file-name)

;; web-mode
;; ========
(require 'web-mode)
(setq web-mode-enable-engine-detection t)
(add-to-list 'auto-mode-alist '("\.djhtml\'" . web-mode))
(add-to-list 'auto-mode-alist '("\.html?\'" . web-mode))
(defun my-web-mode-hook ()
  "Hooks for web-mode."
  (setq web-mode-markup-indent-offset 2))
(add-hook 'web-mode-hook 'my-web-mode-hook)

;; aggressive-indent-mode
;; =======================
(global-aggressive-indent-mode 1)

;; diff-hl
;; =======

Now one of the missing items is the snippets for Django projects, for instance, in Django Templates. To write your own snippets for Django Templates, write the following command to create the necessary file:

$ mkdir -p ~/.emacs.d/snippets/web-mode/django && touch ~/.emacs.d/snippets/web-mode/django/if

and then add the following text to the just created empty file:

# -- mode: snippet --
# name: if statement
# key: if
# --
{% if ${1:condition} %}
{% endif %}

By now, we have created our first snippet using Yasnippet. Using web-mode we need to set the template-engine to django for the correct syntax highlighting. To do it, run the following command in GNU Emacs, when you open an html file which contains Django Template.

M-x web-mode-set-engine

and then choose django. Alternatively you can also add the following text to the top of your html file for the automatic recognition by web-mode (which you get a not-safe warning in GNU Emacs and therefore not preferred)

<!-- -*- engine:django -*--->

And if you only use html in your Django projects, instead of using the above mentioned commands, associate all html files as Django Templates, by adding the following command to your Emacs config file

(setq web-mode-engines-alist
      '(("django" . "\\.html\\'")))

Now, you can enjoy developing your next Django project using GNU Emacs.