These docs are a work-in-progress and are currently undergoing a major rewrite!


We have a strong preference for class-based views. While they can take some getting used to (especially if you have used function-based views in the past), the ability to use mixins and inheritance is a huge benefit.

Forge includes a couple of mixins for common SaaS needs.


In your repo you'll find a BaseLoggedInMixin class. For most applications, you'll want users to be logged in for almost every view, and having a "root" view for this and other logic can be very useful.

class BaseLoggedInMixin(LoginRequiredMixin, HTMLTitleMixin):
    html_title_suffix = " | Built with Forge"

# Usage
class MyView(BaseLoggedInMixin, TemplateView):
    template_name = "my_template.html"

As your app evolves, you might find other logic or context that you want to implement on all downstream views, and the BaseLoggedInMixin can be a useful place to put it.


Adding HTML page titles is important for user experience and many analytics tools. The HTMLTitleMixin provides a simple way to add titles to your templates through Python code and a template variable:

from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import TemplateView

from forge.views.mixins import HTMLTitleMixin

class BaseLoggedInMixin(LoginRequiredMixin, HTMLTitleMixin):
    html_title_suffix = " | Built with Forge"

class HomeView(BaseLoggedInMixin, TemplateView):
    html_title = "Home"
    template_name = "home.html"
<!-- base.template.html -->
<!doctype html>
<html lang="en">
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <title>{% block html_title %}{{ html_title }}{% endblock %}</title>

All available settings for the HTMLTitleMixin class can be found on GitHub →

By default, defining a title is required and this mixin will raise an error if you forget to implement a title. This requirement can be disabled by setting html_title_required to False.

class BaseLoggedInMixin(LoginRequiredMixin, HTMLTitleMixin):
    html_title_suffix = " | Built with Forge"
    html_title_required = False

For views where the title needs to be more dynamic, you can use the get_html_title method to generate it at runtime:

class AccountView(BaseLoggedInMixin, TemplateView):
    def get_html_title(self):

If you find yourself overriding a template for a standard Django view, you can still set the HTML title using the template block if you can't modify the view itself:

<!-- 404.html -->
{% extends "base.html" %}

{% block html_title %}Page not found (404){% endblock %}

{% block content %}
<div class="py-10 text-center">
    <p class="text-6xl text-gray-300">404</p>
    <h1 class="mt-4 text-4xl">Page not found</h1>
{% endblock %}