Debugging Django in VSCode without using --noreload

Sept. 20, 2018


Numerous sites on the internet mention that using the debugger of VSCode with Django is possible but require you to disable the reloading aspect of the runserver (Issue #1057 of ptvsdRemote debugging in Docker (for Django apps)Debug python application running in Docker). I'll show you that this is not actually the case, you can have your cake and eat it too.


The problem stems from the fact that Django loads itself twice in order to support reloading even when Django crashes. The first instance of Django knows you want auto reloading and launches a second instance. This second instance is the one that deals with requests. As soon as it crashes it will be restarted by the first Django. Now if both instances try to claim the same TCP port for remote debugging you'll run into "Address already in use" errors.


The solution then is to make sure the debugger only activates for the second instance, and not for the first. By looking at the source code of Django's utils/autoreload.py and Django-Extensions' management/commands/runserver_plus.py you'll end up with this piece of code that works in unison with the reloading functionality:

import os
import ptvsd

# Only attach the debugger when we're the Django that deals with requests
if os.environ.get('RUN_MAIN') or os.environ.get('WERKZEUG_RUN_MAIN'):
    ptvsd.enable_attach(address=('0.0.0.0', 7913), redirect_output=True)

Happy debugging!