Using Django (Topics)
3.14 Sending email
topics/email
목차
3.14 Sending email
- 01. Quick example
- 02. send_mail()
- 03. send_mass_mail()
- 04. mail_admins()
- 05. mail_managers()
- 06. Examples
- 07. Preventing header injection
- 08. The EmailMessage class
- 09. Email backends
- 10. Configuring email for development
세부목차
3.14 Sending email
- 01. Quick example
- 02. send_mail()
- 03. send_mass_mail()
- send_mass_mail() vs. send_mail()
- 04. mail_admins()
- 05. mail_managers()
- 06. Examples
- 07. Preventing header injection
- 08. The EmailMessage class
- EmailMessage Objects
- Sending alternative content types
- 09. Email backends
- Obtaining an instance of an email backend
- SMTP backend
- Console backend
- File backend
- In-memory backend
- Dummy backend
- Defining a custom email backend
- Sending multiple emails
- 10. Configuring email for development
Sending email
파이썬도 smtplib 모듈을 통해 비교적 쉽게 메일을 보낼 수 있지만, 장고는 그것을 더 쉽게 할 수 있는 방법(=wrappers)을 제공합니다. 이 wrappers는 이메일을 무척 빠르게 전송할 수 있고, 개발단계에서 이메일 전송 테스트를 쉽게 할 수 있습니다. 그리고 SMTP를 사용하지 않는 플랫폼 역시 지원합니다.
이 코드는 django.core.mail 모듈안에 들어 있습니다.
01. Quick example
간단하게 두 줄로 확인해 보겠습니다.
from django.core.mail import send_mail
send_mail(
'subejct here',
'Here is the message.',
'[email protected]',
['[email protected]'],
fail_silently=False,
)
메일은 SMTP 호스트와 포트를 이용해 전송됩니다. 이 호스트와 포트는 settings.py의 EMAIL_HOST와 EMAIL_PORT로 설정합니다. EMAIL_HOST_USER와 EMAIL_HOST_PASSWORD 설정은, 만약 설정한다면, SMTP 서버에서 인증에 사용되고, 그리고EMAIL_USE_TLS와 EMAIL_USE_SSL 설정은 보안연결이 필요할 때, 그것을 조정합니다.
Note
메일에 사용되는 폰트는 DEVAULT_CHARSET의 설정을 따릅니다.
02. send_mail( )
send_mail(subject, message, from_email, recipient_list, fail_silentl=False, auth_user=None, auth_password=None, connection=None, html_message=None)
메일을 보내는 가장 간단한 방법은 django.core.mail.send_mail()을 이용하는 것입니다. 이 때
subject, message, from_email, recipient_list에 대한 설정이 필요합니다.
- subject : 한 줄의 문자열
- message : 한 줄의 문자열
- from_email : 한 줄의 문자열
- recipient_list : 문자열 리스트 하나, 각각의 이메일 주소로 되어 있음. 여기 담긴 각가의 멤버는 다른 수신자를 To 부분에서 확인할 수 있습니다.
- fail_silently : boolean 임. 만약 False 라면 send_mail 은 smtplib.SMTPException을 띄움. smtplip 설명서를 참고할 것. 발생가능한 예외상황을 확인하기 위해. 이 모든 것은 SMTPException의 하위 영역에 속함
- auth_user : 선택적인 유저네임은 SMTP 서버를 인증하는데 사용됩니다. 이것이 제공되지 않는 경우, 장고는 EMAIL_HOST_USER 의 설정을 사용합니다.
- auth_password : 선택적인 패스워드는 SMTP 서버를 인증하는데 사용됩니다. 제공되지 않는 경우 EMAIL_HOST_PASSWORD 설정을 사용합니다.
- connection : 선택적인 이메일 백엔드는 메일을 보내는 데 사용됩니다. 만약 특정하게 지정되지 않는다면, 기존 백엔드의 객체가 사용됩니다. 더 자세한 내용은 Email backends 문서를 참고하세요.
- html_message : 만약 html_message 가 제공되면, 결과물인 메일은 multipart/alternative 이메일이 됩니다. multipart는 text/plain 콘텐츠 타입의 message, alternative는 text/html 타입의 html_message입니다. (아마도)
반환되는 값은 전송에 성공한 메시지의 수입니다 (이것은 0또는 1이 됩니다. 왜냐하면 한번에 하나의 메시지만 보낼 수 있기 때문입니다.)
03. send_mass_mail( )
send_mass_mail(datatuple, fail_silently=False, auth_user=None, auth_password=None, connection=None) [source]
django.core.mail.sedn_mass_mail() 은 다량의 이메일을 보내는 데 사용합니다. datatuple은 아래와 같은 양식의 튜플입니다.
(subject, message, from_email, recipient_list)
fail_silently, auth_user, auth_password는 send_mail()과 동일한 기능입니다.
datatuple의 각각의 분리된 요소들은 분리된 이메일 메시지를 만듭니다. send_mail()에서와 마찬가지로, 동일한 수신자 리스트에 있는 수신자들은 다른 사람들의 주소를 이메일 메시지에서 볼 수 있습니다. ("To"필드)
예를 들어, 아래 코드는 두 개의 서로 다른 메시지를 두 개의 서로 다른 수신자 세트에 보냅니다. 하지만 메일 서버와의 연결은 하나입니다.
message = ('Subject here', 'Here is the message', '[email protected]', ['[email protected]', '[email protected]'])
message = ('Another Subject', 'Here is another message', '[email protected]', ['[email protected]'])
send_mass_mail((message1, message2), fail_silently=False)
반환되는 값은 성공적으로 전송된 메시지의 개수입니다.
send_mass_mail( ) vs. send_mail( )
send_mass_mail()과 send_mail()의 가장 다른 점은, send_mail()은 실행될 때마다 메일 서버와의 연결을 열지만, send_mass_mail()은 모든 메시지에 단일한 연결을 이용한다는 점입니다. 이 점은 send_mass_mail()이 약간 더 효과적이게 만듭니다.
04. mail_admins( )
mail_admins(subject, message, fail_silently=False, connection=None, html_message=None)[souce]
django.core.mail.mail_admins()는 사이트 관리자에게 메일을 보내는 지름길입니다. ADMINS에 정의되어 있습니다.
mail_admins()은 EMAIL_SUBJECT_PREFIX에 설정된 값을 접두사로 제목에 사용합니다. 기본값은 "[Django]"로 설정되어 있습니다.
"From:"이라는 이메일의 머릿말은 SERVER_EMAIL의 설정을 따릅니다.
이 방법(=method)은 편의성과 가독성을 위해 존재합니다.
html_message가 제공된다면, 이메일은 multipart/alternative 이메일이 됩니다. 여기에는 message와 html_message가 사용되는데, message는 text/plain 콘텐츠 타입이고, html_message는 text/html 콘텐츠 타입 입니다.
05. mail_managers()
mail_managers(subject, message, fail_silently=False, connection=None, html_message=None)
소스코드보기4
django.core.mail.mail_managers( )는 mail_admins( )와 동일합니다. 단, 사이트 관리자에게 메일을 보낼 때는 MANAGERS에 설정된 내용을 따릅니다.
06. Examples
아래 예제는 [email protected]과 [email protected]에 같은 내용의 메일을 보냅니다. 두 주소는 모두 "To:" 부분에 나타납니다.
send_mail(
'Subject',
'Message.',
'[email protected]',
['[email protected]', '[email protected]'],
)
아래 예제는 두 주소로 동일한 메시지를 보내지만, 분리된 메일을 받습니다.
datatuple = (
('Subject', 'Message.', '[email protected]', ['[email protected]']),
('Subject', 'Message.', '[email protected]', ['[email protected]']),
)
send_mass_mail(datatuple)
07. Preventing header injection
Header injection은 보안 공격의 일종입니다. 이 경우 공격자는 우리의 스크립트가 생성하는 "To:"와 "From:"을 제어할 수 있는 추가적인 이메일 헤더를 삽입합니다.
문서 앞쪽에서 설명한 장고의 모든 이메일 기능은 헤더 값에 새로운 줄을 만드는 것을 금지하여 header injection을 방지합니다. 만약 어떤 subject, from_email, recipient_list든 간에 새로운 줄을 포함한다면 (Unix, Windows, Mac 스타일에서도 마찬가지입니다.) 장고의 이메일 기능은(e.g. send_mail()) django.core.mail.BadHeaderError를 띄울 것입니다. (이것은 ValueError의 하위 클래스 입니다.) 그리고 이에 따라 이메일은 전송되지 않습니다. 이메일 기능을 통해 전달할 데이터의 검증은 사용자의 책임입니다.
만약 메시지가 문자열의 시작부분에 헤더를 가지고 있다면, 그 헤더는 이메일 메시지의 첫번째 비트로 출력됩니다.
아래는 요청의 POST 데이터에서 subject, message, from_email을 받는 뷰 예제입니다. 이 뷰는 받아온 내용을 [email protected]로 보낸 후, "/contct/thanks/"로 redirect 됩니다.
from django.core.mial import send_mail, BadHeaderError
from django.http import HttpResponse, HttpResponseRedirect
def send_email(request):
subject = request.POST.get('subject', ' ')
message = request.POST.get('message', ' ')
from_email = request.POST.get('from_eamil', ' ')
if subject and message and from_email :
try:
send_mail(subject, message, from_email, ['[email protected]'])
except BadHeaderError:
return HttpResponse('Invalid header found.')
return HttpResponseRedirect('/contact/thanks/')
else:
# 실제로 작업을 할 때는 보다 적절한 검증 에러를 얻기 위해 form class를 사용합니다.
return HttpResponse('Make sure all fields are entered and valid.')
08. The EmailMessage class
장고의 send_mail( )과 send_mass_mail( )기능은 실제로 얇은 wrapper입니다. 이 wrapper는 EmailMessage 클래스를 사용합니다.
하지만 mailMessage클래스의 모든 기능을 사용하지는 못합니다. 만약 숨은 참조 수신자, 파일 첨부, multi-part email과 같이 더 향상된 기능을 사용하고 싶다면 EmailMessage 객체를 직접 만들어야 합니다.
Note
이것은 일종의 디자인 기능입니다. 본래 send_mail( )과 이에 관련된 기능들은 장고가 제공하는 유일한 인터페이스였습니다. 하지만 이 인터페이스가 사용하는 매개 변수의 목록이 시간이 지나며 점차 증가했습니다. 때문에 좀 더 개체기반으로 설계(object-oriented)된 방향으로 이동하면서, 기존의 기능은 이전 버전과의 호환성을 위해서만 유지하는 것이 적절합니다.
EmailMessage는 이메일 메시지를 만드는 역할을, email backnd는 메일을 전송하는 역할을 담당합니다.
편의상, EmailMessage는 하나의 메일을 보낼 수 있는 간단한 send( ) 메소드를 제공합니다. 만약 다중 메시지를 전송해야 한다면 이메일 백엔드 API가 대안을 제공합니다 ('sending multiple emails'5).
09. Email backends
10. Configuring email for development
def mail_managers(subject, message, fail_silently=False, connection=None, html_message=None):
"""
매니저에게 메시지를 보냅니다. MANAGERS에 설정된 대로
"""
if not settings.MANAGERS:
return mail = EmailMultiAlternatives(
'%s%s' % (settings.EMAIL_SUBJECT_PREFIX, subject),
message,
settings.SERVER_EMAIL,
[a[1] for a in settings.MANAGERS],
connections=connections,
)
if html_message:
mail.attach_alternative(html_message, 'text/html')
mail.send(fail_silently=fail_silently)