Then modify <prj-name>/<prj-name>/urls.py
(the global index) to point at
<prj-name>/<app-name>/urls.py.

Running The Development Server

From the project directory <prj-name>:

python manage.py runserver ip-address:port

Middleware & How HTTP Requests Get To A View

WSGI stands for Web Server Gateway Interface and is a specification of how a
webserver can call a Python framework with an HTTP request and get a response.

A WSGI compantible framework will implement a callable object that receives as
parameters the HTTPRequest object and a callback, which it uses to send the HTTP
response headers to the server. The function must then return the HTTP reponse
body as a list of strings.

The start of the processes, clipped in places, is shown below (I took this from the
Django 1.11 source code).

This doesn't yet show how requests get to a view. That'll come. For now, note that
the server will call a core django function, get_wsgi_application()
that returns a callable object. This object is called and passed a dictionary
of CGI-like parametrs (key, value pairs) and a callback function. For example the
dictionary on my machine, when I printed it out, looked something like this:

The parameters will create an
HTTPRequest object, and the callback will be used by Django to send the server
the HTTP headers that will form the reponse. The called object finally must return
the HTTP response body as a list of strings.

When get_wsgi_application() is called it returns a callable object.
The function creates a new instance of a WSGIHandler object. As part
of its construction the Django middleware is loaded by consulting the
list of strings, defined by the variable MIDDLEWARE in the
settings.py file of your Django project.

The WSGIHandler, which is a child of django.core.handlers.base.BaseHandler
loads the middleware using the BaseHandler. It examimes each middleware
object in MIDDLEWARE.

Each middleware object can implement some or all of the the functions

process_view()

process_template_response()

process_exception()

If a middleware object implements a function above, that function is added to
a list of middleware functions of that type that the handler object caches.

The middleware objects must, in addition to the above, form a chain.
The first middleware object created will
point to BaseHandler._get_response(), so it will
call BaseHandler._get_response. The second middleware object points
to the first middle ware and so on.
Only a reference to the last middleware object therefore needs to be remembered.
In this way,
later on, when the middleware chain is executed, the MIDDLEWARE list
is essentially executed in reverse order and the very last thing to execute is
BaseHandler._get_response.

For example, the default MIDDLEWARE that Django spits out for me is this:

So that is how the Django middleware is loaded. That was the arrow in the above
diagram which went to "nowhere"... it was too much to fit that process
into the diagram, but thats what was happening :)

Okay, so, we've loaded the middleware and created the WSGIHandler
object, which is returned to the WSGI server, for it to call with the
CGI-like variables (environment) and the start_response callback
function.

The big bit is how the HTTP response is generated through the call from
WSGIHandler to its base class function get_response().
Here the fun starts...

The WSGI server calls the WSGIHandler object. One of the first things it does is
to send a Django-framework signal. Then it
takes the dictionary passed to it and converts it into a WSGIRequst
object. This class mostly seems to extract more important dictionary key/value
pairs and presents them as object properties. For example, it might parse a GET
request's query string and handle cookies etc.

The meaty bit is the next bit where the respone is processed by calling the base
class method get_response().

The first thing it does it to call the middleware chain. This means the last
module defined in the settings MIDDLEWARE list is called, I.e., all
middleware is a callable of some kind.

It seems all the middleware include the MiddlewareMixin class which is
what defines the __call__() function for the middleware object. This
is found in django.utils.deprecation, so I guess they must be wanting
to get rid of this pretty soon. Anyway, when a middlware is called it implements
the following logic:

Given the above, it is then unsuprising that when adding a few prints into the
relevant funtions we see the following output when requesting a page:

An important point is that if any middleware created a
response in their process_request() method they would break the chain.
This would presumably be if, for example, the security middleware detected some kind
of security issue and didn't want the processing of this HTTP request to continue.
Thus we can say that each middle ware, as well as potentially sanitizing the
request object can also function as a gateway, either allowing the request
to continue or not as it deems fit.

By passing what the various middleware objects are doing (I haven't looked at them
in detail, I'm interested in the view processing here), lets continue. Finally,
after all the middlewares have processed the request and found nothing
illegal/dangerous the last part of the chain _get_response() is called.

It is now that a resolver is created. This is what compares the HTTP
request URL with all of the configured urlpatterns. Once a match is
found a match object continaing a callback, the callback's arguments and keyword
arguments is returned. The callback is in fact the view associated with the url(...)
that the URL matched the HTTP request URL. So, if it was a FBV then it is a function
and if it is a CBV it is a class object that is callable.

Every middleware object in the _view_middleware list mentioned earlier
is now called in order and passed the url-match callback and arguments. The first
one to return an HTTPResonse object "wins" - that is the reponse
that will be used and no views will be called.

Assuming non of the middleware caused a fuss, our view will now be called. For a
FBV this is easy enough to see how - it just calls the function we wrote. For a CBV,
however, we generall don't implement any specific entry point for our class. To understand
how, then, our class is called we must remember we passed it to the url
function using ourClass.as_view(). The function as_view()
is part of the django.views.generic.base.View. It is a Django class method so
can only be called on the class definition and not on a class instance. It
wraps the class inside a closure that returns a function that accepts the HTTPRequest
object and arguments. It is this function that encloses and instance of the view class
that is then called via its dispatch() with the WSGIRequest
object as its first parameter.

The dispatch() method is quite simple "router" that takes
the HTTP request method, converts it to lower case, and then tries to call that method
on the class. Therefore if it was a GET request, it will call the view's get()
method. If it was a POST request it calls the view's post() method and
so on...