Migrera e-post till mailers¶
Django 6.1 introducerade inställningen MAILERS, som ersätter EMAIL_BACKEND och flera andra inställningar av typen EMAIL_*. Det introducerade också mail.mailers för att hämta konfigurerade instanser av e-postbackend, som ersättning för mail.get_connection(). Ett nytt argument, using, ersätter det tidigare connection i Django-funktioner som skickar e-post.
Den här guiden ger information om hur befintliga projekt migreras till den nya mailers-funktionaliteten.
Alla Django-projekt som skickar e-post bör:
Om du använder tredjepartspaket som skickar e-post ska du verifiera deras kompatibilitet med
MAILERSinnan du gör andra ändringar.Kör med utfasningsvarningar aktiverade (se howto/upgrade-version:Hantera utfasningsvarningar) för att identifiera annan kod som behöver uppdateras.
Observera
Att köra tester identifierar kanske inte alla relevanta utfasningar. Testsviter använder ofta en e-postbackend som inte fungerar på riktigt (som minnesbackend som Django ersätter under tester), och kan därför missa utfasningsvarningar som endast utfärdas från e-postkonfigurationen i produktion.
Överväg att köra med utfasningsvarningar aktiverade i produktion för att fånga dessa utfasningar. Du kan också granska koden noggrant (inklusive tredjepartspaket) för användning av utfasade e-postfunktioner.
Andra uppdateringar behövs bara för projekt eller återanvändbara Django-bibliotek som använder dessa specifika funktioner:
Ersatt sedan version 6.1: Följande inställningar och funktioner kommer att tas bort i Django 2028:
EMAIL_BACKEND,EMAIL_FILE_PATH,EMAIL_HOST,EMAIL_HOST_PASSWORD,EMAIL_HOST_USER,EMAIL_PORT,EMAIL_SSL_CERTFILE,EMAIL_SSL_KEYFILE,EMAIL_TIMEOUT,EMAIL_USE_SSL,EMAIL_USE_TLSmail.get_connection()och argumentetconnectiontill e-postfunktionerArgumentet
fail_silentlytillsend_mail(),send_mass_mail(),mail_admins(),mail_managers()ochEmailMessage.send()Argumenten
auth_userochauth_passwordtillsend_mail()ochsend_mass_mail()Argumentet
email_backendtillAdminEmailHandler
Migrera inställningar¶
Ofta är den enda ändring som behövs för att migrera till mailers att uppdatera e-postrelaterade inställningar. I projektets inställningar definierar du en MAILERS-ordbok med en post "default" som motsvarar de tidigare inställningarna EMAIL_*:
MAILERS = {
"default": {
"BACKEND": ..., # value of EMAIL_BACKEND setting
"OPTIONS": {
# values from other deprecated EMAIL_* settings
...,
},
},
}
För att till exempel uppdatera dessa inställningar:
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = "mail.example.net"
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = "user@example.net"
EMAIL_HOST_PASSWORD = "password"
använder du:
MAILERS = {
"default": {
"BACKEND": "django.core.mail.backends.smtp.EmailBackend",
"OPTIONS": {
"host": "mail.example.net",
"use_tls": True,
# port is not needed: it defaults to 587 with use_tls True.
"username": "user@example.net",
"password": "password",
},
},
}
Den fullständiga listan över utfasade inställningar EMAIL_* och vart de ska flyttas i en MAILERS-konfiguration är:
EMAIL_BACKENDblir"BACKEND". Om inställningarna inte definieradeEMAIL_BACKENDvar standardvärdet"django.core.mail.backends.smtp.EmailBackend"(vilket också är standard om enMAILERS-konfiguration inte anger"BACKEND").EMAIL_FILE_PATHblir"file_path"i"OPTIONS"(med"BACKEND"inställt på"django.core.mail.backends.filebased.EmailBackend").EMAIL_HOSTblir"host"i"OPTIONS". En"host"krävs för SMTP-e-postbackend. Om inställningarna inte definieradeEMAIL_HOSTanger du"host"som"localhost"(standardvärdet för den utfasade inställningen).EMAIL_HOST_PASSWORDblir"password"i"OPTIONS".EMAIL_HOST_USERblir"username"i"OPTIONS". (Observera att"username"inte helt följer namnkonventionen för de andra utfasade inställningarna.)EMAIL_PORTblir"port"i"OPTIONS". Det kan utelämnas om anslutningen använder standardporten för sin säkerhet (465 för SSL, 587 för TLS eller 25 för en oskyddad SMTP-anslutning).EMAIL_SSL_CERTFILEblir"ssl_certfile"i"OPTIONS".EMAIL_SSL_KEYFILEblir"ssl_keyfile"i"OPTIONS".EMAIL_TIMEOUTblir"timeout"i"OPTIONS".EMAIL_USE_SSLblir"use_ssl"i"OPTIONS".EMAIL_USE_TLSblir"use_tls"i"OPTIONS".
För tredjeparts- eller anpassade e-postbackendar beror tillgängliga "OPTIONS" på backend. Se dokumentationen från tredje part, eller för anpassade backendar Migrera anpassade e-postbackendar nedan.
Avsnittet Konfigurera e-post innehåller mer information om inställningen MAILERS och ytterligare konfigurationsexempel.
Förbereda återanvändbara bibliotek¶
I de flesta fall fortsätter tredjepartspaket som skickar e-post via Django att fungera med projekt vars inställningar har uppgraderats för att använda MAILERS. (Om de använder utfasade e-postfunktioner kommer dessa förstås att ge utfasningsvarningar.)
Det finns två utfasade funktioner som inte stöds när MAILERS har definierats i ett projekts inställningar:
Att försöka komma åt någon av de utfasade inställningarna
EMAIL_*idjango.conf.settings(till exempel att kontrollerasettings.EMAIL_BACKENDeller användasettings.EMAIL_HOST_USER).Att anropa
mail.get_connection("path.to.EmailBackend")med en specifik backend-sökväg. (Andra argument tillget_connection()stöds fortfarande och ger bara utfasningsvarningar närMAILERSär definierat.)
Om ett tredjepartspaket gör något av detta kommer projekt som använder det inte att kunna byta till inställningen MAILERS förrän paketet har uppdaterats.
Åtgärda fel av typen ”not available when MAILERS is defined”¶
Om något av dessa fel uppstår i ett tredjepartspaket betyder det att paketet inte är kompatibelt med inställningen MAILERS:
AttributeError: "The name setting is not available when MAILERS is defined"där name ärEMAIL_BACKEND,EMAIL_HOSTeller någon annan av de utfasade inställningarna.RuntimeError: get_connection(backend, ...) is not supported with MAILERS.
Om du ser dessa fel, kontrollera om det finns en nyare version av beroendet. Om det inte finns det (och det inte finns något alternativ till paketet) behöver du ta bort MAILERS från inställningarna och ersätta den med motsvarande utfasade e-postinställningar tills paketet har uppdaterats.
Om felen kommer från din egen kod kan du läsa de andra avsnitten i denna migreringsguide för rekommenderade uppdateringar.
Ersätta get_connection() och argumenten connection¶
Ersättningarna för den utfasade funktionen mail.get_connection() och argumenten connection till andra e-postfunktioner beror på hur och varför anslutningarna skapas:
get_connection()anropas utan argumentErsätt med
mailers.default. Uppdatera till exempel denna kod:connection = mail.get_connection() connection.send_messages([email1, email2])
till:
connection = mail.mailers.default connection.send_messages([email1, email2])
Observera att
mailers.defaultär standard för Djangos funktioner som skickar e-post. Kod som denna:mail.send_mail(..., connection=mail.get_connection())
kan uppdateras till:
mail.send_mail(...) # No connection arg needed.
get_connection(fail_silently=True)get_connection(...)anropas med andra argumentDefiniera en anpassad
MAILERS-konfiguration med önskad backend och önskade alternativ. Hänvisa sedan till den med argumentetusingnär e-post skickas, eller hämta en instans av e-postbackend frånmail.mailersmed konfigurationsnamnet.För att till exempel uppgradera denna kod:
connection = mail.get_connection( "path.to.custom.EmailBackend", option1=True, option2="value" ) mail.send_mail(..., connection=connection) connection.send_messages([email1, email2])
Definiera en anpassad
MAILERS-konfiguration i inställningarna:MAILERS = { "default": {...}, "custom": { "BACKEND": "path.to.custom.EmailBackend", "OPTIONS": { "option1": True, "option2": "value", }, }, }
Och använd den sedan så här:
mail.send_mail(..., using="custom") mail.mailers["custom"].send_messages([email1, email2])
Ersätta fail_silently¶
De utfasade argumenten fail_silently till send_mail(), send_mass_mail(), mail_admins(), mail_managers() och EmailMessage.send() kan ersättas på flera sätt. Befintlig användning verkar ha flera olika förväntningar på beteendet, varav många inte stämmer med den faktiska implementationen (som beror på e-postbackend). Överväg att ta bort fail_silently helt om det inte finns ett särskilt behov av det.
Anrop med fail_silently=True bör uppdateras med något av dessa alternativ, beroende på anroparens avsikt:
För att skicka ett meddelande om e-post har konfigurerats men undvika att utlösa ett fel om den inte har det (till exempel i ett återanvändbart bibliotek) omger du sändanropet med
try:/except mail.MailerDoesNotExist: pass.För att ignorera alla undantag (till exempel för att undvika kedjefel i en felhanterare som skickar e-post) omger du sändanropet med
try:/except Exception: pass.För att ignorera enbart SMTP-relaterade fel omger du sändanropet med
try/except OSError: pass. Observera att detta ignorerar både tillfälliga nätverksstörningar och SMTP-konfigurationsproblem (precis som den befintliga implementationen av SMTP-e-postbackendensfail_silently).För att ignorera slutanvändares skrivfel i
to-adresser och andra leveransproblem tar du bort argumentetfail_silently. Mottagarfel upptäcks i allmänhet inte vid sändningstillfället, så att användafail_silentlyför detta ändamål åstadkommer inget och kan maskera andra problem, som konfigurationsfel.(I konfigurationer för lokal leverans kan SMTP-servrar rapportera vissa mottagarfel vid sändning. Om du använder
fail_silentlysärskilt för att ignorera dessa fel bör du i stället överväga att fångaSMTPRecipientsRefusedoch/ellerSMTPResponseExceptions med särskildasmtp_code-värden som ett mer precist filter.)För att skapa en e-postkonfiguration som ignorerar vissa backendberoende fel och återanvända den för flera sändningar skapar du en anpassad
MAILERS-konfiguration med"fail_silently": Truei"OPTIONS"och hänvisar sedan till konfigurationen medusingi sändanropet.
Anrop med fail_silently=False bör uppdateras genom att ta bort argumentet fail_silently, eftersom detta är standard.
Migrera anpassade e-postbackendar¶
Anpassade implementationer av EmailBackend kan behöva uppdateras för kompatibilitet med mailers.
I backendens metod
__init__()ska explicita nyckelordsargument accepteras för alla konfigurationsalternativ som kan komma från"OPTIONS". Backendar som använder anpassade inställningar för konfiguration kan fortsätta att göra det (eller låta bli, enligt eget val), men nyckelordsargument bör ha företräde framför inställningar.Acceptera variabla
**kwargsoch skicka dem till superklassens init. (Detta inkluderar ett nytt argumentaliassom måste skickas till superklassen.) Säkerställ att**kwargssom används av backend inte skickas till superklassens init, eftersom det skulle generera ettInvalidMailer-fel för okända OPTIONS.Backendar måste nu själva hantera
fail_silentlyom de vill stödja det. Det finns inget krav på att stödjafail_silently, och backendar som inte erbjuder det bör ta bort det nyckelordsargumentet. (Skicka inte ett explicit argumentfail_silentlytill superklassens init.)Acceptera inte variabla positionsargument
*argsoch skicka dem inte till superklassens init.
Superklassen BaseEmailBackend initierar nu attributet alias. Det är användbart för felmeddelanden (till exempel raise InvalidMailer(f"Bad host {host}", alias=self.alias)), men bör inte användas för att komma åt settings.MAILERS direkt. Alla OPTIONS för en mailer-konfiguration skickas till backendens init som nyckelordsargument.
För återanvändbara bibliotek som vill stödja kompatibilitet med utfasade e-postfunktioner och inställningar, eller som stöder äldre Django-versioner:
En backend kan upptäcka att den initieras utan
MAILERSgenom att kontrollera omself.alias is None. (Djangos inbyggda backendar kontrollerar detta för att avgöra om utfasade inställningar ska användas.) Bibliotek som stöder äldre Django-versioner behöver användagetattr(self, "alias", None).Backendar som använder Djangos SMTP-e-postinställningar, som
EMAIL_HOST, får inte försöka komma åt dem närMAILERSanvänds (self.alias is not None), eftersom detta orsakar ettAttributeErrormed texten ”not available when MAILERS is defined”.Bibliotek som stöder flera Django-versioner kan identifiera stöd för mailers med antingen
hasattr(django.core.mail, "mailers")ellerdjango.VERSION >= (6, 1).
Ersätta auth_user och auth_password¶
De utfasade argumenten auth_user och auth_password till send_mail() och send_mass_mail() kan ersättas genom att definiera en anpassad MAILERS-konfiguration med "username" och "password" i "OPTIONS" och hänvisa till den konfigurationen med argumentet using när e-post skickas.
För att till exempel uppgradera:
mail.send_mail(..., auth_user="admin", auth_password="admin-password")
Lägg till en anpassad MAILERS-konfiguration i inställningarna:
MAILERS = {
# Existing default configuration.
"default": {
"OPTIONS": {
"host": "smtp.example.com",
"username": "default-user",
"password": "default-password",
},
},
# Duplicate the default configuration, changing the auth.
"admin-config": {
"OPTIONS": {
"host": "smtp.example.com",
"username": "admin",
"password": "admin-password",
},
},
}
Och hänvisa sedan till den vid sändning:
mail.send_mail(..., using="admin-config")
Uppdatera email_backend för AdminEmailHandler¶
Det utfasade argumentet email_backend till loggningsklassen AdminEmailHandler kan ersättas med en anpassad MAILERS-konfiguration, som hänvisas till med argumentet using.
Om inställningarna till exempel innehåller:
LOGGING = {
# ...
"handlers": {
"mail_admins": {
"class": "django.utils.log.AdminEmailHandler",
"email_backend": "third.party.EmailBackend",
},
},
# ...
}
Ersätt detta med:
LOGGING = {
# ...
"handlers": {
"mail_admins": {
"class": "django.utils.log.AdminEmailHandler",
"using": "admin-logging", # defined in MAILERS
},
},
# ...
}
MAILERS = {
"default": {...},
"admin-logging": {
"BACKEND": "third.party.EmailBackend",
},
}