In a nutshell, a Middleware is a regular Python class that hooks into Django’s request/response life cycle. Thoseclasses holds pieces of code that are processed upon every request/response your Django application handles.

  1. Django Custom Test Runner Reviews
  2. Django Custom Test Runner Download
  3. Django Test Db
  4. Django Custom Test Runners

The Middleware classes doesn’t have to subclass anything and it can live anywhere in your Python path. The only thingDjango cares about is the path you register in the project settings MIDDLEWARE_CLASSES.

Your Middleware class should define at least one of the following methods:

  • Called during request:
    • process_request(request)
    • process_view(request, view_func, view_args, view_kwargs)
  • Called during response:
    • process_exception(request, exception) (only if the view raised an exception)
    • process_template_response(request, response) (only for template responses)
    • process_response(request, response)

Updating your app’s tests to work with djangotenants¶ Because django will not create tenants for you during your tests, we have packed some custom test cases and other utilities. If you want a test to happen at any of the tenant’s domain, you can use the test case TenantTestCase. Using a custom test runner to test with celery ¶. If you’re going the CELERYALWAYSEAGER route, which is probably better than just never testing some parts of your app, a custom Django test runner does the trick. Celery provides a simple test runner, but it’s easy enough to roll your own if you have other things that need to be done. And there is a fairly limited bunch of people contributing to both pytest-django and django's test framework. Third, pytest itself does not have complete feature parity with the basic run-tests options of Django's test framework. For example, Django has the -reverse flag to run tests in the reverse order.

How it works?

The Middlware classes are called twice during the request/response life cycle. For that reason, the order you definethe Middlwares in the MIDDLEWARE_CLASSES configuration is important.

Let’s have a look on the built-in Middleware classes the django-admin startproject command sets up:

During the request cycle, the Middleware classes are executed top-down, meaning it will first executeSecurityMiddleware, then SessionMiddleware all the way until XFrameOptionsMiddleware. For each of the Middlewaresit will execute the process_request() and process_view() methods.

At this point, Django will do all the work on your view function. After the work is done (e.g. querying the database,paginating results, processing information, etc), it will return a response for the client.

During the response cycle, the Middleware classes are executed bottom-up, meaning it will first executeXFrameOptionsMiddleware, then MessageMiddleware all the way until SecurityMiddleware. For each of the Middlewaresit will execute the process_exception(), process_template_response() and process_response() methods.

Django Custom Test Runner Reviews

Finally Django will deliver the response for the client. It is important to note that process_exception() is onlyexecuted if a exception occurs inside the view function and process_template_response() is only executed if thereis a template in the response.

The image below was extracted from the official Django documentation and it represents well the process describedabove.

Creating a Custom Middleware

Django custom test runner reviews

To ilustrated this post, let’s create a custom Middleware class that intercept all the exceptions that occur in ourview functions then grab the exception message and query the StackOverflow API and return the three top answers andprint it to the terminal.

I will call it StackOverflow Exception Troubleshooting, or simply SOET. So it’s gonna be a Middleware fordebugging, meant to run only when DEBUG=True.

This is what our Middleware will look like:

Our view function thorws an uncaugh exception, the SOET Middleware process it, search for a solution onStackOverflow, and print the three most relevant results for the developer directly in this terminal window.

Cool right? You will see how easy it is to implement it.

Getting Started

For this example I created a Django app named soet because I wanted to make it available for everyone. I will getback to that later. But if you already have an app that makes sense to create the middleware in, go ahead.

Inside the soet app I created a file named middleware.py. At the moment it looks like that:

Now I gotta register my new Middleware in the MIDDLEWARE_CLASSES configuration:

I’ve registered it as the last one because the process_exception() method is only processed during the responsecycle, and I want my middleware to be executed first so no other Middleware supress the thrown exception.

At this point our brand new Middleware isn’t doing anything really. But it is already being executed. We can test itby putting a print statement inside the process_exception() method. Also it is important that our method alwaysreturn None so to keep the flow of the Middlewares processing. We don’t want to affect the behavior of what isreturned to the client.

Now let’s make sure we are only executing this Middleware if the DEBUG=True:

Consuming the StackOverflow API

The idea now is to use the exception message and the exception name to query the StackOverflow database through its APIin order to find relevant solutions.

To save us some time and avoid struggling with the python standard libraries urllib and urllib2, let’s just use theawesome Requests library.

Also I will not go into much detail about the StackOverflow API. The previous link will take youto the official documentation where you can learn more. That being said, I will stick with the /2.2/search endpoint.

So at this point we are already consuming the StackOverflow API! It is pretty much it. Now we are listing the top 3questions with the tags python and django, displaying its title and the question url.

Runner

Now it is a matter of selecting the right fields and displaying it in the terminal, using the same strategy.

Try it Live

The source code of this little experiment is available on GitHub. The package is alsoavailable on PyPI.

Here is a quick start if you want to try it:

1. Install using pip:

2. Include “soet” to your INSTALLED_APPS:

Django Custom Test Runner Download

3. Include “StackOverflowMiddleware” to your MIDDLEWARE_CLASSES:

Django Test Db

4. Make sure you are running your project with DEBUG=True.

Django Custom Test Runners

5. Start your development server and wait for the view exceptions (or not).