3 Ways You Can Use the Django Redirects App

Here is everything you need to know about Django redirects App and how to use it.

Picture of Nsikak Imoh, author of Macsika Blog
Blank image with background and the text 3 Ways You Can Use the Django Redirects App
Blank image with background and the text 3 Ways You Can Use the Django Redirects App

This post is part of the tutorial series titled Learn to Use Django with FastAPI Frameworks

Table of Content

Django being a batteries-included framework comes with a few optional apps you can easily install and use when required.

One of those apps is the Redirects App.

Here is everything you need to know about Django redirects App and how to use it.

What is Django Redirects App and When Should You use it

Django redirects app is an optional redirects application that lets you store redirects in a database while it handles the redirecting for you.

It uses the HTTP response status code 301 Moved Permanently by default.

The Redirects app is useful when you want to:

  • Update some existing URLs without compromising your Website's SEO
  • Update some existing URLs while avoiding 404 errors.

How does Django Redirect App Work

It basically works by creating a table in the database with two columns, old_path and new_path.

Every time your Website raises a 404 error, the Redirects App will intercept the response and check if the requested URL is found in the column old_path, instead of raising the 404 error, it will redirect the user to the new_path and return a 301 code (Moved Permanently).

How to Install the Django Redirects App

To install the redirects app, follow these steps:

  1. Install the django.contrib.sites framework from django.
  2. Add django.contrib.redirects to your INSTALLED_APPS.
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
    
        'django.contrib.sites',
        'django.contrib.redirects',
    ]
    
    Highlighted code sample.
  3. Set a SITE_ID so the sites framework works properly.
    SITE_ID = 1
    
    Highlighted code sample.
  4. Add django.contrib.redirects.middleware.RedirectFallbackMiddleware to your MIDDLEWARE setting.
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    
        'django.contrib.redirects.middleware.RedirectFallbackMiddleware',
    ]
    
    Highlighted code sample.
  5. Run the migrate command to create the required tables.
    python manage.py migrate
    
    Highlighted code sample.

How to Use the Django Redirects App

The easiest way to use the Django redirects App is through Django Admin.

If you are not currently using the Django Admin app, and it's a one-time thing, you can use just the Python API via command line or create a fixture.

If you are not using Django Admin and still want to add it as a functionality for the site administrator, then you will have to create your own views for it.

1. Use the Redirects App with Django Admin

Using the Django Redirects app with the admin is very straightforward.

You simply add the paths, and Django will handle the rest for you.

To test it:

  • Type the old path in the browser and see if redirects correctly.
  • Another way is examining the response body in the terminal. You can easily do it by using curl:

2. Use the Redirects App with the Python API

To use the redirects app with Python API, you will create the redirect records manually and interact directly with the Redirect model located in django/contrib/redirects/models.py

To do this, start a Python shell with your project models loaded by running the following command:

python manage.py shell
Highlighted code sample.

Create a few redirect entries using the code sample below:

from django.contrib.redirects.models import Redirect
from django.contrib.sites.models import Site
from django.conf import settings

site = Site.objects.get(pk=settings.SITE_ID)

Redirect.objects.create(site=site, old_path='/home.html', new_path='/')
Redirect.objects.create(site=site, old_path='/old-path/old-path-file.html', new_path='/new-path/new-path-file/')
Highlighted code sample.

3. Use the Redirects App with Fixtures

To use the redirects app with fixtures:

  • Create a JSON file following the template of the example below:

    Assume the name of the file is: redirects.json

    	[
    	   {
    	      "model":"redirects.redirect",
    	      "fields":{
    	         "site":1,
    	         "old_path":"/old-path/old-path-file.html",
    	         "new_path":"/new-path/new-path-file/"
    	      }
    	   },
    	   {
    	      "model":"redirects.redirect",
    	      "fields":{
    	         "site":1,
    	         "old_path":"/home.html",
    	         "new_path":"/"
    	      }
    	   }
    	]
    	```
    
    
    Highlighted code sample.
  • Load it directly to your database by running the command below:

    python manage.py loaddata redirects.json
    
    Highlighted code sample.

How to Handle Temporal (302) Redirects with Django Redirects App

When using the Django Redirects app, the redirection saved uses a status code of 301, by default.

That is, a request to the URL will be interpreted as a permanent redirection.

Also, leaving the destination URL blank will result in returning a 410 (“Gone”) status code, no matter what.

Let it handle 302 redirections, instead, Django allows you to easily create a subclass of this particular middleware, should you want to customize it by changing its behavior to handle “302” (Temporal Redirect) or both.

Handle Temporal (301) Redirect

Enter the code below in models.py.

from django.contrib.redirects.middleware import RedirectFallbackMiddleware as BaseRedirectFallbackMiddleware
from django.http import HttpResponseRedirect

class RedirectFallbackMiddleware(BaseRedirectFallbackMiddleware):
    """A middleware handling 302 redirects."""

    response_redirect_class = HttpResponseRedirect
Highlighted code sample.

Handle Both Temporal (301) and Permanent (302) Redirect

from django.contrib.redirects.models import Redirect as BaseRedirect
from django.db import models

class Redirect(BaseRedirect):
    """A redirect."""

    class RedirectTypes(models.IntegerChoices):
        """Redirection types."""
    
        TEMPORARY = 302, "Temporary"
        PERMANENT = 301, "Permanent"
    
    redirect_type = models.IntegerField(
        choices=RedirectTypes.choices
    )
Highlighted code sample.

Next, register the new model in the admin.py.

from django.contrib import admin
from django.contrib.redirects.admin import RedirectAdmin as BaseRedirectAdmin
from django.contrib.redirects.models import Redirect as BaseRedirect

class RedirectAdmin(BaseRedirectAdmin):
    """The redirect admin."""
    
admin.site.unregister(BaseRedirect)
admin.site.register(Redirect, RedirectAdmin)
Highlighted code sample.

Finally, implement the middleware to take the switch into account.

from django.conf import settings
from django.contrib.redirects.middleware import (
RedirectFallbackMiddleware as BaseRedirectFallbackMiddleware,
)
from django.contrib.sites.shortcuts import get_current_site
from django.http import HttpResponsePermanentRedirect, HttpResponseRedirect
from pathlib import Path
from resources.models import Redirect

class RedirectFallbackMiddleware(BaseRedirectFallbackMiddleware):
    """A middleware for handling both 301 and 302 redirections."""

    def process_response(self, request, response):
        """Process the response."""        
        if response.status_code != 404:
            return response
        append_slash = (
            settings.APPEND_SLASH and 
            not Path(request.path).suffix and
            not request.path.endswith("/")
        )
        full_path = (
            request.get_full_path(force_append_slash=append_slash)
        )
        current_site = get_current_site(request)
        try:
            r = Redirect.objects.get(
                site=current_site, old_path=full_path
            )
        except Redirect.DoesNotExist:
            pass
        else:
            redirect_types = {
                301: HttpResponsePermanentRedirect,
                302: HttpResponseRedirect,
            }
            self.response_redirect_class = (
                redirect_types[r.redirect_type]
            )
            if r.new_path == "":
                return self.response_gone_class()
            return self.response_redirect_class(r.new_path)
        return response
Highlighted code sample.

What this code block does is ensure that the request comes from a “404” source URL.

Then it checks that a redirection exists in the db and, if so, assigns the response class depending on that very redirection's type selected in the admin, while still accounting for the 410 status code.

Wrap Off

And that's it!

That is everything you need to know about Django redirects App and how to use it.

If you learned from this tutorial, or it helped you in any way, please consider sharing and subscribing to our newsletter.

Get the Complete Code of Django and FastAPI Combo Tutorials on Github.

Connect with me.

Need an engineer on your team to grease an idea, build a great product, grow a business or just sip tea and share a laugh?