django/django · error · ImproperlyConfigured

{self.__class__.__name__} is missing the login_url attribute

Error message

{self.__class__.__name__} is missing the login_url attribute. Define {self.__class__.__name__}.login_url, settings.LOGIN_URL, or override {self.__class__.__name__}.get_login_url().

What it means

Raised by AccessMixin.get_login_url() (mixins.py:21-31) as ImproperlyConfigured when neither the view's login_url attribute nor settings.LOGIN_URL is set. The login-required / permission-required mixins call get_login_url() inside handle_no_permission() to know where to redirect unauthenticated users. Without a login URL the redirect is impossible, so Django refuses to guess.

Source

Thrown at django/contrib/auth/mixins.py:27

class AccessMixin:
    """
    Abstract CBV mixin that gives access mixins the same customizable
    functionality.
    """

    login_url = None
    permission_denied_message = ""
    raise_exception = False
    redirect_field_name = REDIRECT_FIELD_NAME

    def get_login_url(self):
        """
        Override this method to override the login_url attribute.
        """
        login_url = self.login_url or settings.LOGIN_URL
        if not login_url:
            raise ImproperlyConfigured(
                f"{self.__class__.__name__} is missing the login_url attribute. Define "
                f"{self.__class__.__name__}.login_url, settings.LOGIN_URL, or override "
                f"{self.__class__.__name__}.get_login_url()."
            )
        return str(login_url)

    def get_permission_denied_message(self):
        """
        Override this method to override the permission_denied_message
        attribute.
        """
        return self.permission_denied_message

    def get_redirect_field_name(self):
        """
        Override this method to override the redirect_field_name attribute.
        """
        return self.redirect_field_name

View on GitHub (pinned to b5388a3a80)

Solutions

  1. Set LOGIN_URL in settings.py (e.g. LOGIN_URL = '/accounts/login/').
  2. Alternatively set login_url as a class attribute on the view (e.g. login_url = '/login/').
  3. Or override get_login_url() on the view to compute the URL dynamically.
  4. Run Django's system check framework (manage.py check) during CI to catch missing auth configuration early.

Example fix

# settings.py — BEFORE
# LOGIN_URL not set
# settings.py — AFTER
LOGIN_URL = "/accounts/login/"
# OR per-view
class MyView(LoginRequiredMixin, View):
    login_url = "/login/"
Defensive patterns

Strategy: validation

Validate before calling

from django.conf import settings

LOGIN_URL = getattr(settings, "LOGIN_URL", None)
if not LOGIN_URL:
    raise SystemExit("Set LOGIN_URL in settings before enabling login-required mixins.")

Try / catch

# Do not catch ImproperlyConfigured from get_login_url in dispatch.
# Instead guarantee login_url or settings.LOGIN_URL is set.

Prevention

When it happens

Trigger: A class-based view using LoginRequiredMixin, PermissionRequiredMixin, or UserPassesTestMixin receives an unauthenticated request, dispatch() calls handle_no_permission(), which calls get_login_url(), and both self.login_url (default None) and settings.LOGIN_URL (default None) are falsy. The f-string names the offending class.

Common situations: New project that hasn't set LOGIN_URL yet. A CBV with a loginRequiredMixin but the developer forgot to set LOGIN_URL in settings. Switching from a project-level login_url to a per-view one and removing the setting. LoginRequiredMixin added to a view during a refactor without updating settings.

Related errors


AI-assisted analysis of django/django@b5388a3a80 (2026-08-10). Data as JSON: /api/errors/66ecac322ef23485. Report an issue: GitHub.