Mike Slinn
Mike Slinn

VSCode Debugging and the Django-Oscar Sandbox

Published 2021-03-18. Last modified 2021-06-08.
Time to read: about 4 minutes.

This article is categorized under Django, Django-Oscar, Visual Studio Code.

This post discusses how to use Visual Studio Code to debug a Django webapp, in particular the django-oscar Sandbox demo webapp. Django is a popular web application framework. Django-oscar is a popular e-commerce framework built on Django. The django-oscar Sandbox is important because it demonstrates a baseline of functionality. Grouping Visual Studio Code run configurations together is also discussed.

Public Sandbox

A public instance of the Sandbox site is available at https://latest.oscarcommerce.com.

A sample superuser is installed with credentials:

username: superuser
email: superuser@example.com
password: testing

Sandbox Dependencies

You should set up a virtual environment for Python with the django-oscar dependencies installed, as described in a previous blog post. The most important setup task is to establish a Python virtual environment that contains all of the runtime dependencies required by django-oscar.

The django-oscar Sandbox uses PostgreSQL. You need to install PostgreSQL before attempting to type along with this post. I already had installed PostsgreSQL before attempting this, and it just worked.

Running the Sandbox Locally

To run the django-oscar Sandbox locally:

  1. Clone the django-oscar git project.
    Shell
    (aw) $ git clone git@github.com:django-oscar/django-oscar.git
  2. Move to the top-level directory of the local copy of the django-oscar git project.
    Shell
    (aw) $ cd django-oscar
  3. Run the Sandbox. When I did that the first time there was a long pause after the message Symlinked the 'missing image' image.

    Shell
    (aw) $ sandbox/manage.py runserver
    [2021-03-19 16:13:34,840] Watching for file changes with StatReloader
    Performing system checks...
    
    System check identified no issues (0 silenced).
    March 19, 2021 - 16:13:35
    Django version 3.1.6, using settings 'settings'
    Starting development server at http://127.0.0.1:8000/
    Quit the server with CONTROL-C.
    [2021-03-19 16:13:47,932] "GET / HTTP/1.1" 302 0
    [2021-03-19 16:13:48,305] "GET /en-gb/ HTTP/1.1" 302 0
    [2021-03-19 16:13:53,350] Symlinked the 'missing image' image at /var/work/django/django-oscar/src/oscar/static/oscar/img/image_not_found.jpg into your MEDIA_ROOT at /var/work/django/django-oscar/sandbox/public/media
    [2021-03-19 16:14:12,489] "GET /en-gb/catalogue/ HTTP/1.1" 200 62152
    [2021-03-19 16:14:12,724] "GET /static/oscar/css/styles.css HTTP/1.1" 200 262737
    [2021-03-19 16:14:13,332] "GET /media/cache/c5/de/c5de5d293d7826d354cf6e944aea9cf4.jpg HTTP/1.1" 200 7514
    [2021-03-19 16:14:13,348] "GET /media/cache/07/81/07812dfcb8fbb40907089ab8cd32bbee.jpg HTTP/1.1" 200 10911
    [2021-03-19 16:14:13,357] "GET /media/cache/b0/7c/b07cf93b806e1889182f95153e753f4c.jpg HTTP/1.1" 200 11272
    [2021-03-19 16:14:13,360] "GET /media/cache/69/66/69665c64b9407d2d415cc306beb67b69.jpg HTTP/1.1" 200 8533
    [2021-03-19 16:14:13,368] "GET /media/cache/79/e9/79e994d806edb6fc3c26098321bf70d0.jpg HTTP/1.1" 200 13291
    [2021-03-19 16:14:13,374] "GET /static/debug_toolbar/css/print.css HTTP/1.1" 200 43
    [2021-03-19 16:14:13,374] "GET /static/oscar/js/oscar/ui.js HTTP/1.1" 200 12177
    [2021-03-19 16:14:13,389] "GET /static/debug_toolbar/css/toolbar.css HTTP/1.1" 200 11405
    [2021-03-19 16:14:13,393] "GET /static/debug_toolbar/js/toolbar.js HTTP/1.1" 200 10268
    [2021-03-19 16:14:13,395] "GET /media/cache/ee/d6/eed6bcfd8732ca981f2d25a20233226c.jpg HTTP/1.1" 200 3060
    [2021-03-19 16:14:13,396] "GET /static/oscar/js/bootstrap4/bootstrap.bundle.min.js HTTP/1.1" 200 84378
    [2021-03-19 16:14:13,407] "GET /static/debug_toolbar/js/utils.js HTTP/1.1" 200 2090
    [2021-03-19 16:14:13,505] "GET /static/oscar/webfonts/fa-solid-900.woff2 HTTP/1.1" 200 80252
    [2021-03-19 16:14:14,269] "GET /media/cache/8d/ec/8dec41e2e9e01f7e027963ae409a7e94.jpg HTTP/1.1" 200 6898
    [2021-03-19 16:14:14,276] "GET /media/cache/3b/88/3b885724d0357510cca79e1ba747284e.jpg HTTP/1.1" 200 7318
    [2021-03-19 16:14:14,278] "GET /media/cache/b5/c8/b5c86c8306a16201b5a2fdbf9365411e.jpg HTTP/1.1" 200 9439
    [2021-03-19 16:14:14,322] "GET /media/cache/05/38/0538d9ec40a609c794d3d8afb9d9795e.jpg HTTP/1.1" 200 11893
    [2021-03-19 16:14:14,341] "GET /media/cache/f6/ce/f6cefd110eec94bf700ac9b2702bfaed.jpg HTTP/1.1" 200 12869
    [2021-03-19 16:14:14,413] "GET /media/cache/e2/ee/e2ee6defc4f372adc6e391a2233fde84.jpg HTTP/1.1" 200 5148
    [2021-03-19 16:14:14,871] "GET /media/cache/69/34/6934a369a3609d88f31d8dd1aeb532bb.jpg HTTP/1.1" 200 10897
    [2021-03-19 16:14:14,887] "GET /media/cache/a4/6d/a46dcad8769e5edc74267580c93b186c.jpg HTTP/1.1" 200 8791
    [2021-03-19 16:14:14,925] "GET /media/cache/f8/46/f846c13e10b5009fd2ef885ac949f4d8.jpg HTTP/1.1" 200 7229
    [2021-03-19 16:14:14,926] "GET /media/cache/b4/c8/b4c8668c63927cf4f9867597563db6ff.jpg HTTP/1.1" 200 12052
    [2021-03-19 16:14:14,939] "GET /media/cache/23/f0/23f02272cdf0fac47ace7d4a4e97ade2.jpg HTTP/1.1" 200 5933
    [2021-03-19 16:14:15,066] "GET /static/oscar/favicon.ico HTTP/1.1" 200 1150 

The Sandbox front page looked like this:

Debugging the Local Sandbox

I wanted to use Microsoft Visual Studio Code to set breakpoints, step through executed statements and examine variables. Microsoft has a tutorial for doing this with Django webapps, which was helpful, but needed some extra configuration to work properly, which I show below. The main point of the documentation is that a launch script needs to be created in the Visual Studio Code workspace you are using.

My Visual Studio Code workspace consisted of several top-level directories, including one for this web site (www.mslinn.com), and another for django-oscar.

~/ancientwarmth.code-workspace
{
	"folders": [
		{
			"path": "/mnt/_/www/www.mslinn.com"
		},
		{
			"path": "/mnt/_/www/www.ancientwarmth.com"
		},
		{
			"path": "/mnt/_/work/django/frobshop"
		},
		{
			"path": "/mnt/_/work/django/django-oscar"
		},
		{
			"path": "/mnt/_/work/django/oscar"
		},
		{
			"path": "/mnt/_/work/django/django"
		},
		{
			"path": "/var/work/ancientWarmth"
		},
		{
			"path": "/etc/nginx"
		}
	],
	"settings": {}
}

I already had launch scripts for Ruby programs used by www.mslinn.com.

This is how to create a new launch script for the Sandbox:

  1. Click on the Debug icon at the top left of the Visual Studio Code window:
  2. Click on the Run and Debug pull-down combo box and select the Add Config (django-oscar)... option:
  3. The Microsoft instructions did not match what I saw next. After some messing around, I selected the Python environment from the pull-down combo box at the top of the Visual Studio Code window:
  4. Next I selected the Django debug configuration from the pull-down combo box at the top of the Visual Studio Code window:
  5. Next I selected the Django debug configuration from the pull-down combo box at the top of the Visual Studio Code window:
    The Visual Studio Code documentation defines ${workspaceFolder} as “the path of the folder opened in VS Code”, which works for workspaces with one or more top-level folders. In my case, ${workspaceFolder} is equivalent to the top-level directory for the django-oscar git project.

    I changed the path for program to ${workspaceFolder}/sandbox/manage.py

    The new launch configuration was saved as django-oscar/.vscode/launch.json.

    django-oscar/.vscode/launch.json
    {
      // Use IntelliSense to learn about possible attributes.
      // Hover to view descriptions of existing attributes.
      // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
      "version": "0.2.0",
      "configurations": [
        {
          "name": "Python: Django",
          "type": "python",
          "request": "launch",
          "program": "${workspaceFolder}/sandbox/manage.py",
          "args": [
            "runserver"
          ],
          "django": true
        }
      ]
    }
  6. I discovered that I had to set the path to the Python executable within the virtual environment for django-oscar. The way to do that is to define a new entry in launch.json for "python", like this:

    new line in django-oscar/.vscode/launch.json
    "python": "/var/work/django/oscar/bin/python",
    Instead of hard-coding the absolute path to the virtual environment's python interpreter, it is possible to reference an environment variable. My Linux user account's ~/.bashrc defines an environment variable called oscar with the value /var/work/django/oscar, so the launch.json entry can be written as

    modified new line in django-oscar/.vscode/launch.json
    "python": "${env:oscar}/bin/python",
    I also added arguments to runserver to ensure that it only loaded settings once ("--noreload"), and accepted requests on all IP addresses using port 8003 ("0.0.0.0:8003"). You can read about the allowable options manage.py runserver.

    launch.json now looked like this:

    django-oscar/.vscode/launch.json
    {
      // Use IntelliSense to learn about possible attributes.
      // Hover to view descriptions of existing attributes.
      // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
      "version": "0.2.0",
      "configurations": [
        {
          "name": "Django-Oscar Sandbox",
          "type": "python",
          "request": "launch",
          "program": "${workspaceFolder}/sandbox/manage.py",
          "python": "/var/work/django/oscar/bin/python",
          "args": [
            "runserver"
          ],
          "django": true
        }
      ]
    }
  7. Clicking on the green triangle button at the top left of the Visual Studio Code window invoked the launch script:
    The Django-Oscar Sandbox webapp launched properly. The Visual Studio Code terminal panel showed this output:

    new line in django-oscar/.vscode/launch.json
    $  cd /var/work/django/django-oscar ; /usr/bin/env /usr/bin/python3.8 /home/mslinn/.vscode-server/extensions/ms-python.python-2021.3.658691958/pythonFiles/lib/python/debugpy/launcher 44055 -- /var/work/django/django-oscar/sandbox/manage.py runserver
    [2021-03-19 18:07:17,972] Watching for file changes with StatReloader
    Performing system checks...
    System check identified no issues (0 silenced). March 19, 2021 - 18:07:19 Django version 3.1.6, using settings 'settings' Starting development server at http://127.0.0.1:8002/ Quit the server with CONTROL-C.

I was now able to use Visual Studio Code to set breakpoints, examine variables, etc. 😁

The first thing I did was point my web browser to http:localhost:8003, and I saw the expected Sandbox front page. Clicking on a product's Add to basket link took about 20 seconds to process. During that time I saw a lot of GET requests to /media/cache/.

Grouping Run Configurations

After a while run configurations accumulate and it becomes difficult to choose the one you want. The solution is to define groups of run configurations. Visual Studio Code automatically generates separators between groups. Here you see 5 run configurations grouped together, all showing the AW prefix:

Grouping run configurations is easy. Just add extra JSON to each of the run configurations that you want to group together. The following extra JSON adds the run configuration to the aw group. Run configurations are ordered within their group according to the value of the order attribute.

,
"presentation": {
  "group": "aw",
  "order": 6
}

Here is a complete run configuration:

{
  "justMyCode": true,
  "name": "AW shell",
  "type": "python",
  "request": "launch",
  "program": "${env:aw}/manage.py",
  "python": "${env:venv}/aw/bin/python",
  "args": [
    "shell",
    "--force-local-storage",
    "-i", "python",
  ],
  "django": true,
  "env": {
    "DJANGO_SETTINGS_MODULE": "main.settings.dev"
  },
  "presentation": {
    "group": "aw",
    "order": 6
  }
}