Django

Overview

Django is a python framework for backends/fullstack applications. It offers a high-level approach to web development. It has various tools that helps the developer to write code in a "better" way. For example, it handles SQL queries for the user, making it secure against SQL Injections.

Disclaimer

This file will use the uv package manager. uv however is not required for django. If wanted or needed, use another package manager. Just note, that some commands might not work on your system due to them using the uv cli.

This file also will not explain what uv is or how to use it even if some knowledge of how to use uv is required.

Getting started

The first step to create a django app is to initialize the project. This is done with the following commands. Note that only the dependency will get added. This will not yet create some files for django.

uv init django-tut
cd django-tut
uv add django

The next step is to tell django, that we want to create a new project inside of the src folder. In the following commands, the mysite can be replaced with any other name. The general command scheme just must be fulfilled: django-admin startproject <project-name> src.

mkdir src
uv run django-admin startproject mysite src

Structure

The startproject command will create multiple files, which will be described bere.

manage.py

The manage.py file imports the execute_from_command_line() function from the django.core.management package. This is a CLI to manage this Django project. This is basically the same as the django-admin command, but for this project. To get a full list of what this CLI can do, just run it without any arguments:

uv run ./src/manage.py

To now use the manage.py file to actually execute something, add a flag. For example, you could start the server using:

uv run ./src/manage.py runserver

for a full list of what either manage.py or django-admin can do, consult the official documentation

Note
If you want to know how the django-admin and manage.py differ internally is that manage.py just sets the DJANGO_SETTINGS_MODULE environment variable to point at the settings.py file inside of the current project.

mysite/

The mysite/ directory contains multiple files. Those include the __init__.py, the settings.py, the urls.py as well as the asgi.py and the wsgi.py files. All of these files will be described further on. The main information that you should know is that the mysite/ directory contains a Python package, created by the startproject command. We will do most of the additions inside of those files in this directory.

settings.py

The settings.py file contains the configuration for this Django project. For example, we set our localisation settings here, as well as the database settings. In our project, this database is configured to be at the BASE_DIR/"db.sqlite3".

Another setting that is very important is the DEBUG flag. This will tell Django to either use the debug mode, providing more information about the app than normally, or if it is in production mode. The debug mode should never be enabled in a production environment. You even can create your own settings if wanted, so if you need one or more additional custom setting/s for your web-app, just define it here.

For a documenation of all existing settings in the Django core, please consult the official documentation.

urls.py

This file is used for defining the URL's for the project. It is pure python code and thus it can be created dynamically. The simplest example is automatically generated by the startproject command. It defines just one url and that is the /admin url. This should point to the admin.site.urls page, imported from the django.contrib package.

from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]

asgi.py and wsgi.py

Those are just different deployment platforms for web-servers and applications. Currently, WSGI, short for Web Server Gateway Interface, is the standard, however more and more projects use the ASGI, short for Asynchronous Server Gateway Interface, platform.

The files asgi.py and wsgi.py contain entry points for each of the interfaces.

Database

As already mentioned above, the database is setup in the settings.py file. By default it uses the django.db.backends.sqlite3 backend and this is usually the easiest choice to get started.

In this file there is also the INSTALLED_APPS section, which contains various pre-installed apps, all of which come with Django. These significantly help out with the database setup, authentification and various other things. Some of these apps, like the admin site, needs at least one database table. To create these tables run:

uv run manage.py migrate

To now define some models, alter the polls/models.py file as the following code. This code uses the django.db.models.Model class, where each field is an instance of a Field object. In our example code, those Field-objects will be a CharField and a DateTimeField. In one of the the Field definitions, we will pass an optional first parameter, that add a human-readable name.

from django.db import models

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField("date published")

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

The human-readable name is the DateTimeField("date published"), where the optional string "date published" is passed to the constructor. One thing to add is that we define a foreign key using the ForeignKey class. This tells Django that each Choice is related to a single Question. A Question however can have multiple Choices linked to.

To now use our defined models we need to import them using the INSTALLED_APPS section in mysite/settings.py. Modify the array to contain a reference to polls.apps.PollsConfig:

INSTALLED_APPS = [
    'polls.apps.PollsConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

Note
Django-apps are pluggable. This means that you can create an app in one project but use it in multiple others. This is done to have a more flexible way of seperating concerns. If you have something like a parser of a file, you can just use it again in another project.

No now setup the database with the correct tables, that were defined in polls/models.py run the command below. This will create the tables inside of the database.

uv run manage.py makemigrations polls

The makemigrations will tell Django that changes in the models happened and that those changes should be stored as a migration-file. Migrations are the main way of how Django stores changes to the models (database scheme). Migration-files are stored in polls/migrations/. For example, you should now be able to open the file 0001_initial.py in the folder defined above. They are designed to be human-readable in case that the developer (you) wants to tweak something.

To apply the generated file, run the migrate command from earlier again. This command actually applies all the un-applied database changes and runs them. This basically synchronizes the database and the polls/migrations:

uv run manage.py migrate