How to install a LSP server that supports Django

Before, when developing Django-based projects, I often use VS Code. Because VS Code is heavier and heavier (the installation is 1 GiB now), I need to move away from it. But the first thing is to find an independent LSP server that work well enough with Django. VS Code comes with Pylance, its LSP server for Python. But Pylance is proprietary, so for other code editor, I need a different solution.

When we do programming, LSP servers are great softwares. They help improve productivity by enabling accurate autocomplete in code editor, allowing us to code faster and make less mistakes. They works best with languages having strong type system (Rust and functional programming languages, like Gleam), because the type system let us know at a point, this variable is of which type and has which members. For dynamical type languages, LSP servers often base on a static type checkers (because both need to draw type information from the source code). For Python, the situation is a bit hard, because Python is so dynamic and flexible that, its type annotations cannot cover all the case to help type checkers and LSP servers infer the type of variables. It is especially true for Django. At the time of writing, Mypy is the type checker that supports Django the best. It means that, for LSP server side, we need someone that can take advantage of Mypy. Currently, there are many type checkers + LSP servers for Python, most of them are not written in Python:

  • Pyright: Written in TypeScript.

  • Zuban, Pyrefly, ty: Written in Rust.

Because of that, they cannot run the Mypy plugins that django-stubs project provides to help resolve the dynamic type of Django. Fortunately, I found python-lsp-server, which can talk with Mypy via its pylsp-mypy plugin. The installation is a bit tricky if we choose to install them outside the OS package managers (APT, dnf).

The simplest way to install is via OS package managers. For example, on Ubuntu, we just need to do:

sudo apt install python3-pylsp-mypy

That single command will install both python-lsp-server and pyslp-mypy.

If you don't want to install via OS package manager, because, for example, the OS repositories provide too old version of the software, then the only tool to do is pipx.

pipx is the tool to install Python softwares from PyPI in isolated virtual environment for each. There are several tools of this category (you can use uv tool also). But only pipx supports installing extra packages to an existing isolated virtual environment, and python-lsp-server needs that.

To install python-lsp-server:

❯ pipx install python-lsp-server

  installed package python-lsp-server 1.15.0, installed using Python 3.14.4
  These apps are now available
    - pylsp
done! ✨ 🌟 ✨

then, install the plugin:

❯ pipx inject python-lsp-server pylsp-mypy

  injected package pylsp-mypy into venv python-lsp-server
done! ✨ 🌟 ✨

Check again:

❯ pipx list
venvs are in /home/quan/.local/share/pipx/venvs
apps are exposed on your $PATH at /home/quan/.local/bin
manual pages are exposed at /home/quan/.local/share/man
   package python-lsp-server 1.15.0, installed using Python 3.14.4
    - pylsp

Now we configure the code editor to let it use pylsp.

Helix

Add this to ~/.config/helix/languages.toml file:

[language-server.pylsp]
command = "pylsp"

[[language]]
name = "python"
language-servers = ["ruff", "pylsp"]

Zed

Install pylsp extension.

then in ~/.config/zed/settings.json:

{
  "languages": {
      "Python": {
        "language_servers": ["ruff", "pylsp"]
      }
  }
}

Now see pylsp in action:

django-extra-attribute

With the help of Mypy, pylsp can suggest the extra attribute we define when building QuerySet, not at the model. This magic is what Pyright cannot do.

But... other than that, pylsp is not so complete in term of pure LSP features, like the "hovering" is not working. So in non-Django projects, my choice of LSP + type checker is Zuban.

That's it. Let's enjoy coding and make great softwares together.