Visual Studio 2019 Cheat Sheet for Django

By Krystal Ruwoldt

Updated 11/21/2020


This is a quick reference guide I find myself referring to when creating Django projects in Visual Studio 2019. VS has a great number of shortcuts and inbuilt commands that save heaps of time when developing these projects. I have tried Eclipse and VS Code but I find for my workflow the full fledged VS is the way to go (at least until I try out PyCharm!). I'm writing a series of these 'reference' posts so instead of scrawly notes laying around on my desk and hanging off walls, I can share this useful information with others, besides using just for myself.


Table of Contents


Quick Set-Up of New Django Projects

Starting a new Django project is ridiculously easy using Visual Studio. I often use the in-built Django Web Project template to save a bit of setup time (as a Django project is going to need at least one app!). However there are a few extra initial steps to take before really working from this template, as it uses Django version 2.2.

Visual Studio's Django Web Project Template

Ignore the readme.html page that is displayed upon generating the project, instead clicking on the requirements.txt file to prompt Visual Studio to provide you with a couple of helpful information messages. Go ahead and enable PyTest or UnitTest, as even if you aren't going to set tests up from the outset, enabling testing at this point will save you some time down the track when you do begin testing.

Visual Studio's messages

Clicking Create Virtual Environment opens the Add Environment wizard, which creates the virtual environment and installs Django and the dependencies it needs in the environment for you. If you have the Python Toolbar enabled (View -> Toolbars -> Python) you can see that Visual Studio has you working in this new environment as soon as you create it.

Python Toolbar

I also have the Python Environments window (View -> Other Windows -> Python Environments) pinned behind the Solution Explorer when working with any python project. By clicking the 'package' icon to the right of the Environment drop-down in the Toolbar, this Python Environments window will flick straight over to your virtual environment and display a nice list of your installed packages from PyPI. Then it is just a case of clicking which packages you want to update (ie. Django to latest stable version!) or remove packages if required. I also use the Search field to install any other packages I might require in a project at this point (such as Pillow for dynamic images).

Python Environments window

At this point it's a good idea to generate a new requirements.txt file. This is easy to do from the Solution Explorer, by right-clicking env and selecting Generate requirements.txt from the menu. (I usually just replace the entire file.) You can regenerate the requirements.txt file any time you like with this method (but is particularly helpful after installing or removing packages!).

Generate requirements.txt

You might also want to add your project to source control, which is pretty easy and familiar if you have worked in other languages in Visual Studio, using either GitHub or Azure. Check out the Visual Studio documentation on source control if you need more information. The only suggestion I have here, is that you probably want a better .gitignore file (as the one generated by Visual Studio is a bit lacking when it comes to Python). Check out my .gitignore file for my Django Business Template if you need some ideas on what to add to it.

Finally, you will have some tasks to do such as creating the superuser, generating migrations and applying them (what I call the Usual Django Set-Up Stuff!) which is easily done with Visual Studio's Python Interactive REPLs.

Table of Contents


Python Interactive REPLs

I find the quickest and easiest way in VS to run or access any of the Python or Django Shell commands is through right-clicking on the project in the Solution Explorer and then right-clicking Python. This menu provides all the links for Python and Django Shell terminals relevant to your Python project (the Interactive read-evaluate-print loop (REPL)).

Access Python Commands

Read on for a quick reference for each of these commands.

Table of Contents


Interactive REPLs Reference

Command Line syntax varies, depending on the terminal used and module. Examples of the usage are:

$ django-admin <command> [options]
$ manage.py <command> [options]
$ python -m django <command> [options]

This table shows the equivalent Python/Django command that would be used. Opening these terminals through Visual Studio's Interactive REPL windows from your project will automatically set the scope for which you want to run commands, and makes it very easy to switch scopes if required.

VS Interactive REPL

Equivalent Command

Note

Open Django Shell

shell or dbshell

Django Check

check [list apps]

Django Make Migrations

makemigrations

Django Migrate

migrate

Django Create Superuser

createsuperuser

Relies on django.contrib.auth module

Collect Static Files

collectstatic

Start Server

runserver [port]

Uses StatReloader to watch file changes, also F5 or Ctrl+F5

Start Debug Server

runserver [port]

No StatReloader running

Note that Validate Django App (manage.py validate) and Django Sync DB (manage.py syncdb) are used only in versions 1.6 and lower. Run Mypy and PyLint each open a terminal for these linters (code analyzers).

Table of Contents


Use SQLite DB Browser

I'm a bit of a veteran user of Visual Studio, and working particularly with SQL Server LocalDB, my biggest bug-bear is that with SQLite databases there isn't an obvious built-in tool to view database schema and the actual data. So SQLite DB Browser is the way to go to quickly view the data in the database, among other tasks. It is especially useful when you are trying to implement a complex table structure and you want to be certain the tables have been created as you expect them and there is no odd and unexpected constraints generated from your Django models. Yes we can look at the migration history for this and also use Django Shell to query the database, but having SQLite DB Browser is another handy tool in my kit!

SQLite DB Browser UI

Browsing data of your tables and viewing the pragma statements is just too easy with this small application and is a no-brainer!

Table of Contents


Django Shell for Creating Queries

Finally, Django Shell can be accessed quickly as previously mentioned. In my opinion, using the Django Shell in VS is very useful when creating new queries and testing them out. After importing whatever model/s you want to query:

>>> from myapp.models import MyModel
>>>

Reference the model followed by the model manager, method/s and then execute:

>>> MyModel.objects.all()     (objects -> the default model manager)
<QuerySet [<MyModel: Object 1>, <MyModel: Object 2>]>

I always like to define a string method on all my models so I get readable information returned in even the most basic query, and also define and use my own model managers. So if I was querying the same, say for a 'Package' Model, I'd have something like this example:

>>> from myapp.models import Package
>>> Package.packages.all()
<QuerySet [<Package: Basic Package>, <Package: Great Package>]>

What follows is a useful list (that I refer to a lot!) of Django QuerySet methods and lookups that I use regularly. Refer to the Django documentation (it's very well written and worth it's weight in gold!) as I'm not mentioning EVERY method and lookup here - just the most common. Also note that the links for particular methods scattered through this list jump to that particular reference in the Django documentation. I'm using my Django Small Business Website Template to generate these example queries.

Django Method

SQL Equivalent

Usage & Notes

filter(**kwargs)
WHERE
Method returns new set, can be chained for multiple filters and with exclude(). This produces AND statement queries. eg:
Package.objects.filter(updated__gt=datetime.date(2020, 1, 1), price__lt=100)
Output:
<QuerySet [<Package: Basic Package>]>
For OR, use Q objects.

exclude(**kwargs)
WHERE NOT
Method returns new set, like filter(), can be chained. eg:
Package.objects.filter(period='per month').exclude(updated__lt=datetime.date(2020, 11, 8))
Output:
<QuerySet [<Package: Basic Package>, <Package: Great Package>]>

order_by(*fields)
ORDER BY
Method returns new set, use to override the default ordering meta defined on the model. eg:
Package.objects.filter(updated__year=2020).order_by('-published', 'package_name')
Output:
<QuerySet [<Package: Great Package>, <Package: Basic Package>]>

all()
Method returns new set, pretty straight forward, note that it returns a copy of the current QuerySet or QuerySet subclass. Can use to update data results if the data has changed in the database since QuerySet was first evaluated.

union(*other_qs, all=False)
UNION
Method returns new set, again straight forward, combines results of 2 QuerySets. all=True allows duplicate values. Read the documentation for all the info on UNION, INTERSECT and EXCEPT operators.

values(*fields, **expressions)
Method returns new set, that returns dictionaries, rather than model instances, when used as an iterable. eg:
Package.objects.filter(package_name__startswith='Basic').values('id', 'package_name')
Output:
<QuerySet [{'id': 1, 'package_name': 'Basic Package'}]>

values_list(*fields, flat=False, named=False)
Method returns new set, similar to values() but returns tuples when iterated over. eg:
Package.objects.values_list('id', 'package_name')
Output:
<QuerySet [(1, 'Basic Package'), (2, 'Great Package')]>

select_related(*fields)
Think of it as a LEFT INNER JOIN
Method returns new set, follows Foreign Key relationships and grabs the additional data in the same query, holding in cache so another hit on the database doesn't need occur. eg:
p = OrderItem.objects.select_related('package').get(id=1)
p.package.package_name

Output:
'Basic Package'

prefetch_related(*lookups)
Method returns new set, similar to select_related() but used with many-to-many relationships. Again when used smartly can reduce number of queries and save CPU processing power. Read the documentation! A simple example to show the tags for each service:
services = Service.objects.all().prefetch_related('tags')
for service in services:
   service.tags.all()
Output:
<QuerySet [<Tag: Cats>, <Tag: Heating>, <Tag: Sleeping>]>
<QuerySet [<Tag: Winter>, <Tag: Heating>]>
<QuerySet [<Tag: Heating>, <Tag: Installation>]>

select_for_update(
nowait=False, skip_locked=False, of=())
FOR UPDATE
Method returns new set, locks the rows until transaction is ended. Note that SQLite does not support this and PostgreSQL does not support of use of this method with Window Expressions.

get(**kwargs)
Method returns object that matches lookup parameters, only use parameters that are guaranteed to be unique or will throw errors. Can be used as per the select_related() example or if a queryset is already expected to return just one row:
Package.objects.filter(pk=2).get()
Output:
<Package: Great Package>

count()
COUNT(*)
Method returns integer of number of objects in QuerySet. Only use len(queryset) in place of count() if also wanting to retrieve model instances.
Tag.objects.count()
Output:
7
or:
services = Service.objects.filter(id=1).prefetch_related('tags')
for service in services:
  service.tags.count()

Output:
2

Table of Contents


I hope you found this post useful for using Visual Studio's shortcuts for Django. All information provided is relevant as of writing this, but should things change (as they always do!) I'll update this post as I discover changes. Thanks for reading!