Opened 3 weeks ago

Last modified 2 weeks ago

#35864 closed Cleanup/optimization

EmailMessage.connection option ignored when using send_messages() — at Initial Version

Reported by: Mike Edmunds Owned by:
Component: Core (Mail) Version: 5.1
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

The EmailMessage connection option is ignored when using send_messages() to send multiple messages as suggested in the docs.

Here's some code that won't in fact use special handling for EU users as the author expects:

from django.core import mail

def get_notification_emails():
    notification_emails = []
    for user in get_users_needing_notification():
        email = mail.EmailMultiAlternatives(to=[user.email], ...)
        # Override the ESP for users in the EU; otherwise the default is fine.
        if user.profile.must_use_eu_data_processor():
            email.connection = mail.get_connection(hostname="smtp-eu.example.net")
        notification_emails.append(email)
    return notification_emails

def send_periodic_notification_emails():
    messages = get_notification_emails()
    # We replaced this loop with send_messages() to optimize sending.
    # https://docs.djangoproject.com/en/5.1/topics/email/#sending-multiple-emails
    #   for message in messages:
    #       message.send()
    connection = mail.get_connection()
    connection.send_messages(messages)

(You probably wouldn't make this mistake writing that code all at the same time, but you might stumble into it if those functions were in different files and the send_messages() optimization got added later.)

If we were designing the EmailMessage API from scratch, a clearer design would probably handle connection as an EmailMessage.send() parameter, rather than an EmailMessage property. I don't think it's worth the effort to try to change that now. (But there's an opportunity to avoid similar confusion when we introduce provider as the successor to connection in #35514.)

Suggested fix: in the EmailMessage.connection docs, note that: "This option is ignored when using send_messages()." And maybe in the send_messages() section note that it "overrides any connection option on individual messages."

We could also log a warning in smtp.EmailBackend.send_messages(), if any of the messages has a connection that is not self. (But each EmailBackend implements its own send_messages(), so this wouldn't help with third party backends.)

Change History (0)

Note: See TracTickets for help on using tickets.
Back to Top