Documentation
Topics Overview Overview Linux macOS Windows VS Code for the Web Raspberry Pi Network Additional Components Uninstall VS Code Tutorial Copilot Quickstart User Interface Personalize VS Code Install Extensions Tips and Tricks Intro Videos Overview Setup Quickstart Overview Language Models Context Tools Agents Customization Trust & Safety Overview Agents Tutorial Agents Window Planning Memory Tools Subagents Local Agents Copilot CLI Cloud Agents Third-Party Agents Overview Chat Sessions Add Context Inline Chat Review Edits Checkpoints Artifacts Panel Debug Chat Interactions Prompt Examples Overview Instructions Prompt Files Custom Agents Agent Skills Language Models MCP Hooks Plugins Context Engineering Customize AI Test-Driven Development Edit Notebooks with AI Test with AI Test Web Apps with Browser Tools Debug with AI MCP Dev Guide OpenTelemetry Monitoring Inline Suggestions Smart Actions Best Practices Security Troubleshooting FAQ Cheat Sheet Settings Reference MCP Configuration Workspace Context Display Language Layout Keyboard Shortcuts Settings Settings Sync Extension Marketplace Extension Runtime Security Themes Profiles Overview Voice Interactions Command Line Interface Telemetry Basic Editing IntelliSense Code Navigation Refactoring Snippets Overview Multi-Root Workspaces Workspace Trust Tasks Debugging Debug Configuration Testing Port Forwarding Integrated Browser Overview Quickstart Staging & Committing Branches & Worktrees Repositories & Remotes Merge Conflicts Collaborate on GitHub Troubleshooting FAQ Getting Started Tutorial Terminal Basics Terminal Profiles Shell Integration Appearance Advanced Overview Enterprise Policies AI Settings Extensions Telemetry Updates Overview JavaScript JSON HTML Emmet CSS, SCSS and Less TypeScript Markdown PowerShell C++ Java PHP Python Julia R Ruby Rust Go T-SQL C# .NET Swift Working with JavaScript Node.js Tutorial Node.js Debugging Deploy Node.js Apps Browser Debugging Angular Tutorial React Tutorial Vue Tutorial Debugging Recipes Performance Profiling Extensions Tutorial Transpiling Editing Refactoring Debugging Quick Start Tutorial Run Python Code Editing Linting Formatting Debugging Environments Testing Python Interactive Django Tutorial FastAPI Tutorial Flask Tutorial Create Containers Deploy Python Apps Python in the Web Settings Reference Getting Started Navigate and Edit Refactoring Formatting and Linting Project Management Build Tools Run and Debug Testing Spring Boot Modernizing Java Apps Application Servers Deploy Java Apps GUI Applications Extensions FAQ Intro Videos GCC on Linux GCC on Windows GCC on Windows Subsystem for Linux Clang on macOS Microsoft C++ on Windows Build with CMake CMake Tools on Linux CMake Quick Start C++ Dev Tools for Copilot Editing and Navigating Debugging Configure Debugging Refactoring Settings Reference Configure IntelliSense Configure IntelliSense for Cross-Compiling FAQ Intro Videos Get Started Navigate and Edit IntelliCode Refactoring Formatting and Linting Project Management Build Tools Package Management Run and Debug Testing FAQ Overview Node.js Python ASP.NET Core Debug Docker Compose Registries Deploy to Azure Choose a Dev Environment Customize Develop with Kubernetes Tips and Tricks Overview Jupyter Notebooks Data Science Tutorial Python Interactive Data Wrangler Quick Start Data Wrangler PyTorch Support Azure Machine Learning Manage Jupyter Kernels Jupyter Notebooks on the Web Data Science in Microsoft Fabric Foundry Toolkit Overview Foundry Toolkit Copilot Tools Create Agents Models Playground Agent Builder Agent Inspector Evaluation Tool Catalog Fine-Tuning (Automated Setup) Fine-Tuning (Project Template) Model Conversion Tracing Profiling (Windows ML) FAQ File Structure Manual Model Conversion Manual Model Conversion on GPU Setup Environment Without Foundry Toolkit Template Project Migrating from Visualizer to Agent Inspector Overview Getting Started Resources View Deployment VS Code for the Web - Azure Containers Azure Kubernetes Service Kubernetes MongoDB Remote Debugging for Node.js Overview SSH Dev Containers Windows Subsystem for Linux GitHub Codespaces VS Code Server Tunnels SSH Tutorial WSL Tutorial Tips and Tricks FAQ Overview Tutorial Attach to Container Create Dev Container Advanced Containers devcontainer.json Dev Container CLI Tips and Tricks FAQ Default Keyboard Shortcuts Default Settings Substitution Variables Tasks SchemaOn this page there are 13 sections
Django Tutorial in Visual Studio Code
Django is a high-level Python framework designed for rapid, secure, and scalable web development. Django includes rich support for URL routing, page templates, and working with data.
In this Django tutorial, you create a simple Django app with three pages that use a common base template. You create this app in the context of Visual Studio Code in order to understand how to work with Django in the VS Code terminal, editor, and debugger. This tutorial does not explore various details about Django itself, such as working with data models and creating an administrative interface. For guidance on those aspects, refer to the Django documentation links at the end of this tutorial.
The completed code project from this Django tutorial can be found on GitHub: python-sample-vscode-django-tutorial.
If you have any problems, you can search for answers or ask a question on the Python extension Discussions Q&A.
Prerequisites
To successfully complete this Django tutorial, you must do the following (which are the same steps as in the general Python tutorial):
-
Install the Python extension.
-
Install a version of Python 3 (for which this tutorial is written). Options include:
- (All operating systems) A download from python.org; typically use the Download Python 3.9.1 button that appears first on the page (or whatever is the latest version).
- (Linux) The built-in Python 3 installation works well, but to install other Python packages you must run sudo apt install python3-pip in the terminal.
- (macOS) An installation through Homebrew on macOS using brew install python3 (the system install of Python on macOS is not supported).
- (All operating systems) A download from Anaconda (for data science purposes).
-
On Windows, make sure the location of your Python interpreter is included in your PATH environment variable. You can check the location by running path at the command prompt. If the Python interpreter's folder isn't included, open Windows Settings, search for "environment", select Edit environment variables for your account, then edit the Path variable to include that folder.
Create a project environment for the Django tutorial
In this section, you create a virtual environment in which Django is installed. Using a virtual environment avoids installing Django into a global Python environment and gives you exact control over the libraries used in an application. A virtual environment also makes it easy to Create a requirements.txt file for the environment.
The Python Environments extension supports multiple environment types including venv, conda, poetry, and others. This tutorial uses venv because it's built into Python and requires no additional tools. The steps for other environment types are similar — see Creating environments for details.
-
On your file system, create a project folder for this tutorial, such as hello_django.
-
Open the project folder in VS Code by running code ., or by running VS Code and using the File > Open Folder command.
-
Create a virtual environment using the Python: Create Environment command:
- Open the Command Palette (⇧⌘P (Windows, Linux Ctrl+Shift+P))
- Search for and select Python: Create Environment
- Select Venv to create a venv environment
- Select a Python interpreter to use for the environment
VS Code creates a .venv folder in your workspace and automatically selects the new environment.
TipYou can also create environments by using the Python sidebar. Expand Environment Managers and select the + button for Quick Create, which uses sensible defaults.
-
The selected environment appears on the right side of the VS Code status bar, with the ('.venv': venv) indicator showing that you're using a virtual environment:
-
Install Django in the virtual environment using one of these methods:
Using the Package Management UI:
- In the Python sidebar, expand Environment Managers
- Right-click on your .venv environment and select Manage Packages
- Search for django and select Install
Using the terminal:
Run Terminal: Create New Terminal (⌃⇧` (Windows, Linux Ctrl+Shift+`)) from the Command Palette, which creates a terminal and automatically activates the virtual environment. Then run:
django-admin startproject web_project .This startproject command assumes (by use of . at the end) that the current folder is your project folder, and creates the following within it:
-
manage.py: The Django command-line administrative utility for the project. You run administrative commands for the project using python manage.py <command> [options].
-
A subfolder named web_project, which contains the following files:
- __init__.py: an empty file that tells Python that this folder is a Python package.
- asgi.py: an entry point for ASGI-compatible web servers to serve your project. You typically leave this file as-is as it provides the hooks for production web servers.
- settings.py: contains settings for Django project, which you modify in the course of developing a web app.
- urls.py: contains a table of contents for the Django project, which you also modify in the course of development.
- wsgi.py: an entry point for WSGI-compatible web servers to serve your project. You typically leave this file as-is as it provides the hooks for production web servers.
-
Create an empty development database by running the following command:
Watching for file changes with StatReloader Performing system checks... System check identified no issues (0 silenced). June 13, 2023 - 18:38:07 Django version 4.2.2, using settings 'web_project.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK.Django's built-in web server is intended only for local development purposes. When you deploy to a web host, however, Django uses the host's web server instead. The wsgi.py and asgi.py modules in the Django project take care of hooking into the production servers.
If you want to use a different port than the default 8000, specify the port number on the command line, such as python manage.py runserver 5000.
-
Ctrl+click the http://127.0.0.1:8000/ URL in the terminal output window to open your default browser to that address. If Django is installed correctly and the project is valid, you see the default page shown below. The VS Code terminal output window also shows the server log.
-
When you're done, close the browser window and stop the server in VS Code using Ctrl+C as indicated in the terminal output window.
Create a Django app
-
In the VS Code Terminal with your virtual environment activated, run the administrative utility's startapp command in your project folder (where manage.py resides):
from django.http import HttpResponse def home(request): return HttpResponse("Hello, Django!") -
Create a file, hello/urls.py, with the contents below. The urls.py file is where you specify patterns to route different URLs to their appropriate views. The code below contains one route to map root URL of the app ("") to the views.home function that you just added to hello/views.py:
from django.contrib import admin from django.urls import include, path urlpatterns = [ path("", include("hello.urls")), path('admin/', admin.site.urls) ] -
Save all modified files.
-
In the VS Code Terminal, again with the virtual environment activated, run the development server with python manage.py runserver and open a browser to http://127.0.0.1:8000/ to see a page that renders "Hello, Django".
Create a debugger launch profile
You're probably already wondering if there's an easier way to run the server and test the app without typing python manage.py runserver each time. Fortunately, there is! You can create a customized launch profile in VS Code, which is also used for the inevitable exercise of debugging.
-
Switch to Run view in VS Code (using the left-side activity bar or F5). You may see the message "To customize Run and Debug create a launch.json file". This means that you don't yet have a launch.json file containing debug configurations. VS Code can create that for you if you click on the create a launch.json file link:
-
Select the link and VS Code will prompt for a debug configuration. Select Django from the dropdown and VS Code will populate a new launch.json file with a Django run configuration. The launch.json file contains a number of debugging configurations, each of which is a separate JSON object within the configuration array.
-
Scroll down to and examine the configuration with the name "Python: Django":
path("hello/<name>", views.hello_there, name="hello_there"),The first argument to path defines a route "hello/" that accepts a variable string called name. The string is passed to the views.hello_there function specified in the second argument to path.
URL routes are case-sensitive. For example, the route /hello/<name> is distinct from /Hello/<name>. If you want the same view function to handle both, define paths for each variant.
-
Replace the contents of views.py with the following code to define the hello_there function that you can step through in the debugger:
from django.shortcuts import render -
Also in views.py, modify the hello_there function to use django.shortcuts.render method to load a template and to provide the template context. The context is the set of variables for use within the template. The render function takes the request object, followed by the path to the template relative to the templates folder, then the context object. (Developers typically name the templates the same as the functions that use them, but matching names are not required because you always refer to the exact filename in your code.)
from django.contrib.staticfiles.urls import staticfiles_urlpatterns -
In that same file, add the following line at the end, which includes standard static file URLs to the list that the project recognizes:
.message { font-weight: 600; color: blue; } -
In templates/hello/hello_there.html, add the following lines after the <title> element. The {% load static %} tag is a custom Django template tag set, which allows you to use {% static %} to refer to a file like the stylesheet.
<span class="message">Hello, there {{ name }}!</span> It's {{ date | date:'l, d F, Y' }} at {{ date | time:'H:i:s' }}. -
Run the app, navigate to a /hello/name URL, and observe that the message renders in blue. Stop the app when you're done.
Use the collectstatic command
For production deployments, you typically collect all the static files from your apps into a single folder using the python manage.py collectstatic command. You can then use a dedicated static file server to serve those files, which typically results in better overall performance. The following steps show how this collection is made, although you don't use the collection when running with the Django development server.
-
In web_project/settings.py, add the following line that defines a location where static files are collected when you use the collectstatic command:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>{% block title %}{% endblock %}</title> {% load static %} <link rel="stylesheet" type="text/css" href="{% static 'hello/site.css' %}"/> </head> <body> <div class="navbar"> <a href="{% url 'home' %}" class="navbar-brand">Home</a> <a href="{% url 'about' %}" class="navbar-item">About</a> <a href="{% url 'contact' %}" class="navbar-item">Contact</a> </div> <div class="body-content"> {% block content %} {% endblock %} <hr/> <footer> <p>© 2018</p> </footer> </div> </body> </html> -
Add the following styles to static/hello/site.css below the existing "message" style, and save the file. (This walkthrough doesn't attempt to demonstrate responsive design; these styles simply generate a reasonably interesting result.)
"Django Tutorial: template extending layout.html": { "prefix": "djextlayout", "body": [ "{% extends \"hello/layout.html\" %}", "{% block title %}", "$0", "{% endblock %}", "{% block content %}", "{% endblock %}" ], "description": "Boilerplate template that extends layout.html" }, -
Save the html.json file (⌘S (Windows, Linux Ctrl+S)).
-
Now, whenever you start typing the snippet's prefix, such as djext, VS Code provides the snippet as an autocomplete option, as shown in the next section. You can also use the Insert Snippet command to choose a snippet from a menu.
For more information on code snippets in general, refer to Creating snippets.
Use the code snippet to add pages
With the code snippet in place, you can quickly create templates for the Home, About, and Contact pages.
-
In the templates/hello folder, create a new file named home.html, Then start typing djext to see the snippet appear as a completion:
When you select the completion, the snippet's code appears with the cursor on the snippet's insertion point:
-
At the insertion point in the "title" block, write Home, and in the "content" block, write <p>Home page for the Visual Studio Code Django tutorial.</p>, then save the file. These lines are the only unique parts of the extended page template:
-
In the templates/hello folder, create about.html, use the snippet to insert the boilerplate markup, insert About us and <p>About page for the Visual Studio Code Django tutorial.</p> in the "title" and "content" blocks, respectively, then save the file.
-
Repeat the previous step to create templates/hello/contact.html using Contact us and <p>Contact page for the Visual Studio Code Django tutorial.</p>.
-
In the app's urls.py, add routes for the /about and /contact pages. Be mindful that the name argument to the path function defines the name with which you refer to the page in the {% url %} tags in the templates.
# Replace the existing home function with the one below def home(request): return render(request, "hello/home.html") def about(request): return render(request, "hello/about.html") def contact(request): return render(request, "hello/contact.html")
Run the app
With all the page templates in place, save views.py, run the app, and open a browser to the home page to see the results. Navigate between the pages to verify that the page templates are properly extending the base template.
Work with data, data models, and migrations
Many web apps work with information stored in a database, and Django makes it easy to represent the objects in that database using models. In Django, a model is a Python class, derived from django.db.models.Model, that represents a specific database object, typically a table. You place these classes in an app's models.py file.
With Django, you work with your database almost exclusively through the models you define in code. Django's "migrations" then handle all the details of the underlying database automatically as you evolve the models over time. The general workflow is as follows:
- Make changes to the models in your models.py file.
- Run python manage.py makemigrations to generate scripts in the migrations folder that migrate the database from its current state to the new state.
- Run python manage.py migrate to apply the scripts to the actual database.
The migration scripts effectively record all the incremental changes you make to your data models over time. By applying the migrations, Django updates the database to match your models. Because each incremental change has its own script, Django can automatically migrate any previous version of a database (including a new database) to the current version. As a result, you need concern yourself only with your models in models.py, never with the underlying database schema or the migration scripts. You let Django do that part!
In code, too, you work exclusively with your model classes to store and retrieve data; Django handles the underlying details. The one exception is that you can write data into your database using the Django administrative utility loaddata command. This utility is often used to initialize a data set after the migrate command has initialized the schema.
When using the db.sqlite3 file, you can also work directly with the database using a tool like the SQLite browser. It's fine to add or delete records in tables using such a tool, but avoid making changes to the database schema because the database will then be out of sync with your app's models. Instead, change the models, run makemigrations, then run migrate.
Types of databases
By default, Django includes a db.sqlite3 file for an app's database that's suitable for development work. As described on When to use SQLite (sqlite.org), SQLite works fine for low to medium traffic sites with fewer than 100 K hits/day, but is not recommended for higher volumes. It's also limited to a single computer, so it cannot be used in any multi-server scenario such as load-balancing and geo-replication.
For these reasons, consider using a production-level data store such as PostgreSQL, MySQL, and SQL Server. For information on Django's support for other databases, see Database setup. You can also use the Azure SDK for Python to work with Azure storage services like tables and blobs.
Define models
A Django model is again a Python class derived from django.db.model.Models, which you place in the app's models.py file. In the database, each model is automatically given a unique ID field named id. All other fields are defined as properties of the class using types from django.db.models such as CharField (limited text), TextField (unlimited text), EmailField, URLField, IntegerField, DecimalField, BooleanField. DateTimeField, ForeignKey, and ManyToMany, among others. (See the Model field reference in the Django documentation for details.)
Each field takes some attributes, like max_length. The blank=True attribute means the field is optional; null=true means that a value is optional. There is also a choices attribute that limits values to values in an array of data value/display value tuples.
For example, add the following class in models.py to define a data model that represents dated entries in a simple message log:
python manage.py makemigrations python manage.py migrateTake a look in the migrations folder to see the scripts that makemigrations generates. You can also look at the database itself to see that the schema is updated.
If you see errors when running the commands, make sure you're not using a debugging terminal that's left over from previous steps, as they may not have the virtual environment activated.
Use the database through the models
With your models in place and the database migrated, you can store and retrieve data using only your models. In this section, you add a form page to the app through which you can log a message. You then modify the home page to display those messages. Because you modify many code files here, be mindful of the details.
-
In the hello folder (where you have views.py), create a new file named forms.py with the following code, which defines a Django form that contains a field drawn from the data model, LogMessage:
{% extends "hello/layout.html" %} {% block title %} Log a message {% endblock %} {% block content %} <form method="POST" class="log-form"> {% csrf_token %} {{ form.as_p }} <button type="submit" class="save btn btn-default">Log</button> </form> {% endblock %}Note: Django's {% csrf_token %} tag provides protection from cross-site request forgeries. See Cross Site Request Forgery protection in the Django documentation for details.
-
In the app's static/hello/site.css file, add a rule to make the input form wider:
path("log/", views.log_message, name="log"), -
In views.py, define the view named log_message (as referred to by the URL route). This view handles both HTTP GET and POST cases. In the GET case (the else: section), it just displays the form that you defined in the previous steps. In the POST case, it retrieves the data from the form into a data object (message), sets the timestamp, then saves that object at which point it's written to the database:
<!-- Insert below the link to Home --> <a href="{% url 'log' %}" class="navbar-item">Log Message</a> -
Run the app and open a browser to the home page. Select the Log Message link on the nav bar, which should display the message logging page:
-
Enter a message, select Log, and you should be taken back to the home page. The home page doesn't yet show any of the logged messages yet (which you remedy in a moment). Feel free to log a few more messages as well. If you want, peek in the database using a tool like SQLite Browser to see that records have been created. Open the database as read-only, or otherwise remember to close the database before using the app, otherwise the app will fail because the database is locked.
-
Stop the app when you're done.
-
Now modify the home page to display the logged messages. Start by replacing the contents of app's templates/hello/home.html file with the markup below. This template expects a context variable named message_list. If it receives one (checked with the {% if message_list %} tag), it then iterates over that list (the {% for message in message_list %} tag) to generate table rows for each message. Otherwise the page indicates that no messages have yet been logged.
.message_list th,td { text-align: left; padding-right: 15px; } -
In views.py, import Django's generic ListView class, which we'll use to implement the home page:
# Remove the old home function if you want; it's no longer used class HomeListView(ListView): """Renders the home page, with a list of all messages.""" model = LogMessage def get_context_data(self, **kwargs): context = super(HomeListView, self).get_context_data(**kwargs) return context -
In the app's urls.py, import the data model:
home_list_view = views.HomeListView.as_view( queryset=LogMessage.objects.order_by("-log_date")[:5], # :5 limits the results to the five most recent context_object_name="message_list", template_name="hello/home.html", ) -
In urls.py, modify the path to the home page to use the home_list_view variable:
# This path is included by default when creating the app path("admin/", admin.site.urls), -
Run the server, then open a browser to the app's /admin page (such as http://127.0.0.1:8000/admin when using the development server).
-
A login page appears, courtesy of django.contrib.auth. Enter your superuser credentials.
-
Once you're authenticated, you see the default administration page, through which you can manage users and groups:
You can customize the administrative interface as much as you like. For example, you could provide capabilities to edit and remove entries in the database. For more information on making customizations, refer to the Django admin site documentation.
Create a container for a Django app using the Container Tools extension
The Container Tools extension makes it easy to build, manage, and deploy containerized applications from Visual Studio Code. If you're interested in learning how to create a Python container for the Django app developed in this tutorial, check out the Python in a container tutorial, which will walk you through how to:
- Create a Dockerfile file describing a simple Python container.
- Build, run, and verify the functionality of a Django app.
- Debug the app running in a container.
Next steps
Congratulations on completing this walkthrough of working with Django in Visual Studio Code!
The completed code project from this tutorial can be found on GitHub: python-sample-vscode-django-tutorial.
In this tutorial, we've only scratched the surface of everything Django can do. Be sure to visit the Django documentation and the official Django tutorial for many more details on views, templates, data models, URL routing, the administrative interface, using other kinds of databases, deployment to production, and more.
To try your app on a production website, check out the tutorial Deploy Python apps to Azure App Service using Docker Containers. Azure also offers a standard container, App Service on Linux, to which you deploy web apps from within VS Code.
You may also want to review the following articles in the VS Code docs that are relevant to Python: