Management interface
A management interface in its own file is useful, especially as projects grow in size and complexity. Thus, we have a file called manage.py wherein we can include the following:
import os
from django.core.management import execute_from_commandline
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
execute_from_commandline()This allows us to remove all the irrelevant management code out of our main application file.
Note
We do not need to call
django.setup()in the application file becauseexecute_from_commandline()takes care of it if called before any other setup code.
Minimum functionality
The minimum functionality required to serve a simple web page with Django is the following:
from django.conf import settings
from django.http import HttpResponse
from django.urls import path
from django.core.handlers.wsgi import WSGIHandler
from django.core.management import \
execute_from_command_lineThe simplest version of a home page requires the following settings:
settings.configure(
ROOT_URLCONF=__name__,
DEBUG=True,
SECRET_KEY="secret"
)ROOT_URLCONF is the root URL configuration. It tells Django where to find the URLs to listen for - in this case it is the current file (in __name__), so they must be defined somewhere down the line.
In more complex projects we can extract all the settings into a separate file. Such a file might look as follows:
from pathlib import Path
ROOT_URLCONF="blogmaker" # Assuming the URLs are defined in blogmaker.py
DEBUG=True
SECRET_KEY="my-secret-key"
TEMPLATES=[
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [Path(__file__).parent / "templates"],
}
]Important
One of the most important parts of a separate
settingsfile is to ensure thatROOT_URLCONFpoints at whatever file has our URL configuration.
Separating the settings into a new file also requires changes in the main file. In particular, we need to load the os library as well as django itself
...
import os
...
import django
...
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
django.setup()
...The important line here is to set up environment variables via os.environ.setdefault. This creates a variable called “DJANGO_SETTINGS_MODULE” with a value of settings. That, along with django.setup() takes care of configuring the application with the settings we defined.
Viewing functions
Because Django follows a model-view-controller architecture we must define how data can be viewed. The most basic view function is:
def index(request):
return HttpResponse("A response")The request object passed into Django contains the HTTP request made, and can be used for authentication and other things. In the case above, all of that is ignore and a simple HTTP Response is sent back with the text included. This of course can be later modified to send back templates, for example.
URL patterns
By default Django will listens for URLs that arrive through localhost:8000. However, we must define the patterns that it will listen to, and how to route those patterns to a view function.
This is done in a variable called urlpatterns, and in this case we specify a path that those patterns will take:
urlpatterns = [
path("", index)
]The basic composition of a URL is as follows:
>>> base_url = "http://localhost:8000"
>>> url_parts = ""
>>> url = base_url + "/" + url_parts
>>> url
'http://localhost:8000/'WSGI
WSGI is a web server gateway interface. Another way to think about it is that WSGI is the web server that controls the Python process - WSGI recieves requests and routes them into Django, Django processes the requests, gives a response back to WSGI which itself serves to the clients.
Note that although WSGI is in fact a web server, we often put Nginx or another more dedicated web server infront as a proxy to manage a lot of the traffic.