From 99a14b6be85793f3371779cd9bf6fb9d9247f475 Mon Sep 17 00:00:00 2001 From: badereddinebenhirt Date: Sat, 13 Jun 2026 17:38:54 +0100 Subject: [PATCH] Fixed #37161 -- Warned via system check on missing "default" entry in MAILERS setting. Thanks Mike Edmunds for reviews. Co-authored-by: Natalia <124304+nessita@users.noreply.github.com> --- django/core/checks/__init__.py | 1 + django/core/checks/mail.py | 29 ++++++++++++++++ django/core/checks/registry.py | 1 + docs/ref/checks.txt | 10 ++++++ docs/releases/6.1.txt | 6 ++++ tests/check_framework/test_mail.py | 55 ++++++++++++++++++++++++++++++ 6 files changed, 102 insertions(+) create mode 100644 django/core/checks/mail.py create mode 100644 tests/check_framework/test_mail.py diff --git a/django/core/checks/__init__.py b/django/core/checks/__init__.py index faca2a337d0b..7f2f21989daf 100644 --- a/django/core/checks/__init__.py +++ b/django/core/checks/__init__.py @@ -20,6 +20,7 @@ import django.core.checks.compatibility.django_4_0 # NOQA isort:skip import django.core.checks.database # NOQA isort:skip import django.core.checks.files # NOQA isort:skip +import django.core.checks.mail # NOQA isort:skip import django.core.checks.model_checks # NOQA isort:skip import django.core.checks.security.base # NOQA isort:skip import django.core.checks.security.csrf # NOQA isort:skip diff --git a/django/core/checks/mail.py b/django/core/checks/mail.py new file mode 100644 index 000000000000..49fcf0d8e4fc --- /dev/null +++ b/django/core/checks/mail.py @@ -0,0 +1,29 @@ +from django.conf import settings +from django.core.checks import Tags, Warning, register +from django.core.mail import DEFAULT_MAILER_ALIAS + + +@register(Tags.mail) +def check_mailers_default_alias(app_configs, **kwargs): + if not settings.is_overridden("MAILERS"): + return [] + + if DEFAULT_MAILER_ALIAS in settings.MAILERS: + return [] + + if settings.MAILERS: + hint = ( + f"Add a '{DEFAULT_MAILER_ALIAS}' entry to MAILERS, or pass 'using' when " + "sending email." + ) + else: + hint = f"Add a '{DEFAULT_MAILER_ALIAS}' entry to MAILERS." + + return [ + Warning( + f"Your MAILERS setting has no '{DEFAULT_MAILER_ALIAS}' entry. Sending " + "email without a valid mailer will fail.", + hint=hint, + id="mail.W001", + ) + ] diff --git a/django/core/checks/registry.py b/django/core/checks/registry.py index 257dadac41b6..32657ce12cfc 100644 --- a/django/core/checks/registry.py +++ b/django/core/checks/registry.py @@ -17,6 +17,7 @@ class Tags: compatibility = "compatibility" database = "database" files = "files" + mail = "mail" models = "models" security = "security" signals = "signals" diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index 462736782325..3928057c84d8 100644 --- a/docs/ref/checks.txt +++ b/docs/ref/checks.txt @@ -84,6 +84,7 @@ Django's system checks are organized using the following tags: or if you specify configured database aliases using the ``--database`` option when calling the :djadmin:`check` command. * ``files``: Checks files related configuration. +* ``mail``: Checks email related configuration. * ``models``: Checks of model, field, and manager definitions. * ``security``: Checks security related configuration. * ``signals``: Checks on signal declarations and handler registrations. @@ -151,6 +152,15 @@ If you're using MySQL or MariaDB, the following checks will be performed: * **mysql.W003**: MySQL/MariaDB may not allow unique ``CharField``\s to have a ``max_length`` > 255. +Mail +---- + +The following checks verify that your :setting:`MAILERS` setting is correctly +configured: + +* **mail.W001**: Your :setting:`MAILERS` setting has no ``'default'`` entry. + Sending email without a valid mailer will fail. + Managing files -------------- diff --git a/docs/releases/6.1.txt b/docs/releases/6.1.txt index 03a9b8cdfd0a..c441709057e4 100644 --- a/docs/releases/6.1.txt +++ b/docs/releases/6.1.txt @@ -237,6 +237,12 @@ CSP :func:`~django.template.context_processors.csp` context processor is configured. See :ref:`csp-nonce-config` for setup instructions. +Email +~~~~~ + +* A new ``mail.W001`` system check warns when :setting:`MAILERS` is defined but + does not include a ``'default'`` entry. + Forms ~~~~~ diff --git a/tests/check_framework/test_mail.py b/tests/check_framework/test_mail.py new file mode 100644 index 000000000000..a67e147e9282 --- /dev/null +++ b/tests/check_framework/test_mail.py @@ -0,0 +1,55 @@ +from django.core.checks import Warning +from django.core.checks.mail import check_mailers_default_alias +from django.test import SimpleTestCase, override_settings + + +class MailersDefaultAliasCheckTests(SimpleTestCase): + def test_mailers_not_defined(self): + self.assertEqual(check_mailers_default_alias(None), []) + + @override_settings( + MAILERS={ + "default": { + "BACKEND": "django.core.mail.backends.smtp.EmailBackend", + } + } + ) + def test_mailers_default_alias_configured(self): + self.assertEqual(check_mailers_default_alias(None), []) + + @override_settings(MAILERS={}) + def test_mailers_empty(self): + self.assertEqual( + check_mailers_default_alias(None), + [ + Warning( + "Your MAILERS setting has no 'default' entry. Sending email " + "without a valid mailer will fail.", + hint="Add a 'default' entry to MAILERS.", + id="mail.W001", + ) + ], + ) + + @override_settings( + MAILERS={ + "secondary": { + "BACKEND": "django.core.mail.backends.smtp.EmailBackend", + } + } + ) + def test_mailers_without_default_alias(self): + self.assertEqual( + check_mailers_default_alias(None), + [ + Warning( + "Your MAILERS setting has no 'default' entry. Sending email " + "without a valid mailer will fail.", + hint=( + "Add a 'default' entry to MAILERS, or pass 'using' when " + "sending email." + ), + id="mail.W001", + ) + ], + )