Epic VS Code Setup for Django development

Introduction

Setting up your development environment properly can be extremely helpful in making you more productive. Adding tools such as linters and automated code formatters helps ensure that the code you write uses consistent formatting, can help eliminate certain bugs, and improves your developer experience (DX). It also allows you to focus on what your code is doing rather than how it looks, preventing bike-shedding.

In this blog post, we will have a look at how to set up VS Code for professional-level Django development, with some useful tools and extensions.

Do note that I am of the opinion that an ideal development environment is POSIX-based, so Linux or Mac OS makes many things easier and I have not tested this on Windows.

While every project differs and not all of them share the same stack, we will look into some common tools for Python, Django, Tailwind CSS, Docker, etc.

Also note that I am not a VS Code expert... an actual epic dev setup uses Neovim, but I am trying to keep things approachable for developers of all levels.

Finally, note that this is a fairly opinionated post, but it is pretty much industry standard. The important thing is to find a style that works for you and stay consistent. If you're ready, start by installing VS Code if necessary, and opening it.

Time to install extensions

While some IDEs like IntelliJ (Java) or PyCharm (Python) are tailored to specific languages, VS Code and other editors like Neovim are very language-agnostic. That means that they occasionally lack more advanced features. Thankfully, we can install extensions to extend their capabilities and have better integration of whatever language we are working on.

As professional Django and Python developers, the following VS Code extensions are must-haves, so install them now:

Let's create an Epic config

.editorconfig for general editor options

As per the project's description, "EditorConfig helps maintain consistent coding styles for multiple developers working on the same project across various editors and IDEs. The EditorConfig project consists of a file format for defining coding styles and a collection of text editor plugins that enable editors to read the file format and adhere to defined styles. EditorConfig files are easily readable and they work nicely with version control systems."

You can create a file named .editorconfig in your project's root directory with the following content.

# Standardize editor settings for the entire project
# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
indent_style = space
trim_trailing_whitespace = true

# CSS, HTML, and JavaScript
[*.{css,html,js,json}]
indent_size = 2

# Python config
[*.py]
indent_size = 4

Feel free to modify it to fit your preferences and project's needs. You can visit the EditorConfig website for details.

pyproject.toml for Python tools

The pyproject.toml file can be used to configure projects for building and packaging using tools like Poetry, but can also be used to configure many other tools like linters and formatters on a per-project basis. You can configure many of the extensions listed above by creating a pyproject.toml file in your project, either in the root directory, or if you use e.g. Docker Compose, inside the directory containing the Django container. Please see the tools' documentation for specific configuration details, but here is an example pyproject.toml with some very aggressive linter settings.

[tool.black]
line-length = 119
target-version = ['py311']
extend-exclude = "(migrations)"
# Exclude these even if they're passed explicitly as a CLI argument.
# This is necessary for pre-commit to not reformat them.
force-exclude = "(migrations)"

[tool.django-stubs]
# Point this to your settings module, e.g. "myproject.settings"
django_settings_module = "django.settings"

[tool.djlint]
indent = 2

[tool.mypy]
exclude = [
  "migrations",
  "tests",
  "manage.py",
  "(a|w)sgi.py",
]
plugins = [
  "mypy_django_plugin.main",
]

[[tool.mypy.overrides]]
module = [
  "djangorestframework.*",
  "wagtail.*",
]
ignore_missing_imports = true

[tool.ruff]
extend-exclude = ["migrations"]
extend-select = ["A", "B", "C4", "C90", "COM", "D", "DJ", "I", "LOG", "N", "PTH", "RUF", "SIM", "W"]
fix = false
line-length = 119
target-version = "py311"

.vscode/settings.json for a shared Workspace config

I recommend adding a workspace settings file to your project by creating a .vscode/settings.json file inside your project root. For example, the following settings enable automatic formatting as well as linting Django templates.

{
  "[css]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true
  },
  "[html][django-html]": {
    "editor.defaultFormatter": "monosans.djlint",
    "djlint.enableLinting": true
  },
  "[python]": {
    "editor.defaultFormatter": "ms-python.black-formatter",
    "editor.formatOnSave": true,
  }
}

.prettierrc.yml for TailwindCSS

If you use TailwindCSS, I highly recommend including a package.json file in your project, e.g. inside a tailwind/ or node/ directory, and adding prettier-plugin-tailwindcss as a dev dependency. You can then configure VS Code to automatically sort Tailwind classes by enabling the plugin in a prettierrc.yml file as follows.

plugins:
  - prettier-plugin-tailwindcss
Settings