Django Request Lifecycle

What happens when…

An age-old question that crops up in job interviews is “What happens when you type a URL your web browser’s address bar and press enter” or variations on the theme. This type of question can help demonstrate your domain knowledge, communication skills and understanding of the audience.

How you answer this question depends on your experience and expertise and there are numerous topics that you could go delve into:

  • Browser address bar - Response to user input with autocompletion
  • DNS lookup - Locate server IP address
  • Physical network - transmission of packets via modems, switches, routers
  • TCP connections - data flow via a socket
  • TLS handshake - HTTPS and HTTP protocol for data exchange
  • Load balancing - Server resiliency with dynamic IPs
  • Server request handling - Client connecting and sending data
  • Browser content parsing - HTML, CSS & JS
  • Browser page rendering - DOM & CSSOM constructed to display page on screen

For the following example the question has been set in an interview for a Python developer role at a Django-centric company. So the domain knowledge that you want to demonstrate will relate to the web server and Django application with perhaps indication of how the browser renders a page.

As I am relatively new to Django and still learning it myself, I will breakdown the answer into stages to demonstrate layering of the architecture principles and best practices. For an actual interview this layering may not be practical time-wise so would likely keep to discussing the entire architecture.

Simple View

Starting with the URL entered into the address bar, the browser converts the URL entered into an IP address using DNS which identifies the location of the server the browser needs to send it’s request to. For a production website the IP address is usually a load balancer that evenly distribute load between a group of application servers and will transparently select an available backend server.

To communicate with the server the browser will open a TCP socket connection, perform a TLS handshake, assuming HTTPS website here, and then send an HTTP request using the GET method to retrieve the page.

This HTTP request is handled first by a web server such as Nginx or Apache which may handle some of the static files needs by the application such as images, CSS or Javascript. However our request will be routed by a configured rule to a Python WSGI (or ASGI) server such as uWSGI or Gunicorn which passes the request onto the Django web application.

Once Django receives the request it will be converted to an HttpRequest object that is submitted to the URL dispatcher. The URL dispatcher maps the URL path to a view function which when called will process the request and return a response containing HTML data.

simple view lifecycle

View to a template

In the above example the HTML is contained within our view but we can make use of Django templates to write more dynamic and reusable content, rendering the template with context data from within a view into HTML data. A template may contain variables, tags for logic and filters for transformation. When the template is rendered the variables are replaced with values from the context and tags and filters are executed to produce the final HTML data.

simple view template lifecycle

Model, View, Template

We have arrived at the final stage of the Django request lifecycle where stored data can be dynamically added using models. This is the Django Model-View-Template software design pattern. The view will call the model to get or set data used in the response. The data is stored in a relational database and abstracted from model by the Django ORM to make it safer and simpler to perform queries.

Thus we get our final diagram of the request lifecycle:

model view lifecycle

There a few extra details I have added to this diagram. Middleware is an important aspect of the lifecycle of a request which provide hooks to enable custom code to be run at any stage on the request or response objects. Also the simple Template object has been swapped for a TemplateResponse which will defer rendering of the template up until the response is actually returned, enabling potential modifications by middleware after the view.

I will wrap up the request lifecycle for a Django application here. I have kept to the happy path for our request so not talked about error or exception handling and I have not mentioned how the browser parses and renders the HTML response data but that could be a future post.

References