django/django · error · ImproperlyConfigured

The list filter '%' does not specify a 'title'.

Error message

The list filter '%' does not specify a 'title'.

What it means

Every ListFilter (and its subclasses) must expose a human-readable title attribute shown in the admin sidebar. ListFilter.__init__ checks self.title and raises ImproperlyConfigured if it is None, because the template would otherwise render an empty filter header. FieldListFilter auto-derives title from the field's verbose_name, but custom filters that subclass ListFilter or SimpleListFilter directly must set title themselves.

Source

Thrown at django/contrib/admin/filters.py:36

    reverse_field_path,
)
from django.core.exceptions import ImproperlyConfigured, ValidationError
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _


class ListFilter:
    title = None  # Human-readable title to appear in the right sidebar.
    template = "admin/filter.html"

    def __init__(self, request, params, model, model_admin):
        self.request = request
        # This dictionary will eventually contain the request's query string
        # parameters actually used by this filter.
        self.used_parameters = {}
        if self.title is None:
            raise ImproperlyConfigured(
                "The list filter '%s' does not specify a 'title'."
                % self.__class__.__name__
            )

    def has_output(self):
        """
        Return True if some choices would be output for this filter.
        """
        raise NotImplementedError(
            "subclasses of ListFilter must provide a has_output() method"
        )

    def choices(self, changelist):
        """
        Return choices ready to be output in the template.

        `changelist` is the ChangeList to be displayed.
        """

View on GitHub (pinned to ae25a40be0)

Solutions

  1. Add a title class attribute: class MyFilter(admin.SimpleListFilter): title = 'My Filter'.
  2. For SimpleListFilter, also set parameter_name (a separate check) — both are required.
  3. If using FieldListFilter, title is auto-derived so this only triggers for fully custom filters.

Example fix

// before
class PublishedFilter(admin.SimpleListFilter):
    parameter_name = 'published'
    # missing title
    def lookups(self, request, model_admin): return [('yes', 'Yes')]
    def queryset(self, request, qs): return qs

// after
class PublishedFilter(admin.SimpleListFilter):
    title = 'Published'
    parameter_name = 'published'
    def lookups(self, request, model_admin): return [('yes', 'Yes')]
    def queryset(self, request, qs): return qs
Defensive patterns

Strategy: validation

Validate before calling

def validate_list_filter(filter_cls):
    if getattr(filter_cls, "title", None) is None:
        raise TypeError(f"{filter_cls.__name__} must define a non-None 'title' attribute.")
    return filter_cls

Type guard

def has_title(filter_cls) -> bool:
    return getattr(filter_cls, "title", None) is not None

Prevention

When it happens

Trigger: Raised in ListFilter.__init__ (filters.py:35-39) when instantiating a filter whose class sets title = None (the default) and does not override it. Fires when Django builds the changelist filter sidebar for a ModelAdmin whose list_filter references such a filter class.

Common situations: Writing a custom SimpleListFilter and forgetting to set title. Copying a filter skeleton that omitted title. Subclassing ListFilter directly (rather than SimpleListFilter) and missing required attributes.

Related errors


AI-assisted analysis of django/django@ae25a40be0 (2026-08-06). Data as JSON: /api/errors/bbad780eeb0f8e05. Report an issue: GitHub.