Edit:
- After Pydev 2.2.1, this feature has been added, just act like this one, please see http://pydev.org/manual_adv_remote_debugger.html#django-remote-debugging-with-auto-reload
If you are a django newbie and want to develop django application in pydev, see this article first: Configuring pydev to work with django.
This post will focus on how to debug django without –noreload option.
Configuring pydev to work with django this article mentioned that:
“If you want to keep the auto-reloader and still debug, you’ll have to use the remote debugger that comes with the extensions to debug, as it does not rely on having the process started from Eclipse. Check http://www.fabioz.com/pydev/manual_adv_remote_debugger.html for more details.”
I tried it and feel it is a very bad way to debug django application. I use auto reload feature because its dynamic and convenient. But if follow the article to do that, I must insert a line: “import pydevd; pydevd.settrace()” in my source code to set a breakpoint. How silly of this way? If I want to trace the source code in django itself, I must modify the source code of django just for a breakpoint. What if I forget to remove this line…?
Ok, you can give it up that, debug django with –noreload option, not really bad, right? This is true if your web application do not need to login. Every time my partner debug its code, he must change the code, restart django server and login again, then to see the result and do real debug. Restart and login again is a redundant operation in debugging and very wasting time (I know I can use some automation tool such as Selenium to reduce my pain, but it is also inconvenient). The django’s charming productivity is gone.
After some digging into source code of django and pydev, I found a easy way to debug django in pydev with autoreload feature. This way is also using pydev extension’s remote debugger, but the annoy operation which inserts a “import pydevd; pydevd.settrace()” is no more needed. You can set a breakpoint like before and debug it with autoreload feature. The django’s productivity is back!
How to do that? This is simple, you must modify your manage.py and insert these code:
(This code requires pydevd module, please see Configuring pydev to work with django to know where to find it.)
if settings.DEBUG and (command == "runserver" or command == "testserver"):
# Make pydev debugger works for auto reload.
try:
import pydevd
except ImportError:
sys.stderr.write("Error: " +
"You must add org.python.pydev.debug.pysrc to your PYTHONPATH.")
sys.exit(1)
from django.utils import autoreload
m = autoreload.main
def main(main_func, args=None, kwargs=None):
import os
if os.environ.get("RUN_MAIN") == "true":
def pydevdDecorator(func):
def wrap(*args, **kws):
pydevd.settrace(suspend=False)
return func(*args, **kws)
return wrap
main_func = pydevdDecorator(main_func)
return m(main_func, args, kwargs)
autoreload.main = main
This code overrides the django’s autoreload behavior to make pydev can communicate with it. The knowledge behind it is a little complex, so I don’t explain it in here.
If you want to debug without –noreload, you must start remote debugger first, then run django server in pydev (no matter debug mode or not). Eclipse will suspend while it run on your breakpoints. You can modify code and do not need to restart django server to debug it. Try it!
