فصل ۱۵ — ارسال ایمیل در Django (با سناریوی فروشگاه آنلاین)

۱. مقدمه — چرا ارسال ایمیل مهم است؟
توی هر وبسایت حرفهای، ارسال ایمیل یکی از ستونهای اصلی ارتباط با کاربره:
- تأیید ثبتنام
- ارسال فاکتور خرید
- یادآوری پرداخت
- اطلاعرسانیهای مهم (مثل تغییر سیاستها یا آپدیت محصول)
در سناریوی فروشگاه آنلاین ما:
- وقتی کاربر ثبتنام میکنه → ایمیل خوشآمدگویی + لینک تأیید ارسال میشه
- وقتی خرید انجام میده → فاکتور خرید و جزئیات سفارش ایمیل میشه
- وقتی رمز عبور رو فراموش میکنه → لینک بازیابی ایمیل میشه
۲. تنظیمات اولیه ارسال ایمیل در Django
Django سیستم Email Backend داخلی داره که میتونه از یه SMTP واقعی استفاده کنه یا حتی ایمیل رو تو کنسول چاپ کنه (برای تست).
۲.۱. حالت تست (Console Backend)
این روش توی مراحل توسعه خیلی کاربردیه چون ایمیل واقعی ارسال نمیشه، فقط تو ترمینال چاپ میشه.
در settings.py:
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
حالا هر ایمیلی که بفرستیم تو کنسول دیده میشه.
۲.۲. حالت SMTP (برای ارسال واقعی)
برای ارسال ایمیل واقعی، باید SMTP واقعی پیکربندی کنیم.
میتونیم از Gmail SMTP یا سرویسهای تخصصی مثل SendGrid / Mailgun / Amazon SES استفاده کنیم.
مثال با Gmail:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'your_email@gmail.com' # ایمیل شما
EMAIL_HOST_PASSWORD = 'your_app_password' # پسورد برنامه (App Password)
DEFAULT_FROM_EMAIL = 'فروشگاه آنلاین <your_email@gmail.com>'
📌 نکته ۱: برای Gmail باید 2FA رو فعال کنی و App Password بسازی.
📌 نکته ۲: EMAIL_PORT برای TLS → 587 ، برای SSL → 465.
۳. توابع ارسال ایمیل در Django
Django چند ابزار آماده برای ارسال ایمیل داره:
| تابع | کارکرد |
|---|---|
send_mail | سادهترین روش ارسال ایمیل |
EmailMessage | ارسال ایمیل پیشرفتهتر با پیوست |
EmailMultiAlternatives | ارسال چند نسخه (متنی/HTML) در یک ایمیل |
۴. مثال ۱ — ارسال ایمیل خوشآمدگویی (send_mail)
views.py
from django.core.mail import send_mail
from django.conf import settings
from django.shortcuts import render, redirect
from django.contrib import messages
from .forms import RegisterForm
def register(request):
if request.method == "POST":
form = RegisterForm(request.POST)
if form.is_valid():
user = form.save()
# ارسال ایمیل خوشآمدگویی
send_mail(
subject="🎉 خوش آمدید به فروشگاه ما!",
message="از اینکه عضو ما شدید خوشحالیم. لذت خرید خوبی داشته باشید.",
from_email=settings.DEFAULT_FROM_EMAIL,
recipient_list=[user.email],
fail_silently=False
)
messages.success(request, "ثبتنام موفق بود. ایمیل خوشآمدگویی ارسال شد.")
return redirect('home')
else:
form = RegisterForm()
return render(request, 'register.html', {'form': form})
📌 توضیح:
fail_silently=False→ اگه مشکلی بود خطا میده. برای محیط پرو بهتره True باشه.- داخل
recipient_listمیشه چندین ایمیل گذاشت.
۵. مثال ۲ — ارسال ایمیل HTML (EmailMultiAlternatives)
گاهی فقط متن ساده کافیه، ولی برای ایمیلهای زیبا (با استایل و تصویر) باید HTML بفرستیم.
views.py
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
def send_invoice(user, order):
subject = f"🧾 فاکتور خرید شماره {order.id}"
from_email = settings.DEFAULT_FROM_EMAIL
to = [user.email]
# نسخه متنی
text_content = f"سفارش شما با شماره {order.id} ثبت شد."
# نسخه HTML با قالب جداگانه
html_content = render_to_string('emails/invoice.html', {'order': order, 'user': user})
msg = EmailMultiAlternatives(subject, text_content, from_email, to)
msg.attach_alternative(html_content, "text/html")
msg.send()
📌 این روش بهترین برای ایمیلهای پیشرفته هست چون:
- کاربرانی که HTML رو نمیبینن → نسخه متنی دریافت میکنن
- میشه از قالب Django برای HTML استفاده کرد
۶. پیوستکردن فایل (PDF فاکتور)
با EmailMessage یا EmailMultiAlternatives میشه فایل پیوست کرد:
msg.attach_file('/path/to/invoice.pdf')
در سناریوی فروشگاه، میشه فاکتور PDF رو بعد از پرداخت به ایمیل کاربر فرستاد.
۷. ارسال ایمیل آسنکرون (Celery)
ارسال ایمیل بعضی وقتا طول میکشه و سرعت صفحه رو کم میکنه.
بهترین روش اینه که کار رو به Task Queue مثل Celery بدیم.
مثال ساده:
# tasks.py
from celery import shared_task
from django.core.mail import send_mail
from django.conf import settings
@shared_task
def send_async_email(subject, message, recipient_list):
send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, recipient_list)
بعد توی view:
send_async_email.delay("سلام", "این یک ایمیل تستی است", ["user@example.com"])
۸. ایمیل تأیید ثبتنام با لینک فعالسازی
یکی از سناریوهای مهم:
- کاربر ثبتنام میکنه
- ایمیل حاوی لینک تأیید براش ارسال میشه
- تا زمانی که لینک رو نزنه، حسابش فعال نمیشه
📌 مراحل:
- ایجاد توکن فعالسازی
- ساخت URL
- ارسال ایمیل حاوی لینک
- ساخت view فعالسازی
۹. ایمیل بازیابی رمز عبور (Password Reset)
Django خودش سیستم آماده داره:
PasswordResetViewPasswordResetConfirmView
فقط لازمه قالبها و تنظیمات ایمیل رو آماده کنیم.
۱۰. نکات امنیتی برای ارسال ایمیل
- اطلاعات SMTP رو در
.envنگه دار (نه در کد اصلی) - از TLS/SSL استفاده کن
- محدودیت Speed و تعداد ایمیل رعایت شه (SMTP ممکنه بلاک کنه)
- ایمیلهای حساس رو حتماً رمزنگاری یا روی HTTPS بفرست
۱۱. تست ارسال ایمیل در محیط توسعه
- Console Backend → بهترین روش برای تست سریع
- File Backend → ایمیلها رو تو فایل ذخیره میکنه:
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = '/tmp/django-emails'
۱۲. خطاهای رایج
| خطا | علت | راهحل |
|---|---|---|
smtplib.SMTPAuthenticationError | رمز یا ایمیل اشتباه | App Password استفاده کن |
| ایمیل اسپم میشه | IP یا دامنه جدید | SPF/DKIM/DMARC پیکربندی کن |
| ایمیل ارسال نمیشه | فایروال یا بلاک پورت | پورت SMTP رو باز کن |
۱۳. بهترین روشها (Best Practices)
- همه متنها و HTML رو در قالبها نگه دار، نه در کد
- ارسال ایمیلهای طولانی یا حجیم رو آسنکرون کن
- لاگ خطاهای ایمیل رو ذخیره کن
- لینکها رو با
reverse()یاabsolute_uri()بساز
۱۴. مثال جامع سناریوی فروشگاه: ارسال فاکتور خرید
فرض کن بعد از پرداخت موفق:
views.py
from django.contrib import messages
from .utils import send_invoice # تابعی که قبلاً نوشتیم
def payment_success(request, order_id):
order = get_object_or_404(Order, id=order_id, user=request.user)
# ارسال ایمیل
send_invoice(request.user, order)
messages.success(request, "پرداخت موفق بود. فاکتور خرید به ایمیل شما ارسال شد.")
return redirect('order_detail', pk=order.id)
با این روش الان فروشگاه آنلاین ما:
- ایمیل خوشآمدگویی رو میفرسته
- فاکتور خرید PDF + HTML ارسال میکنه
- قابلیت بازیابی رمز عبور از طریق ایمیل داره
- از خطاهای SMTP جلوگیری شده