فصل ۱۵ — ارسال ایمیل در 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"])

۸. ایمیل تأیید ثبت‌نام با لینک فعال‌سازی

یکی از سناریوهای مهم:

  • کاربر ثبت‌نام می‌کنه
  • ایمیل حاوی لینک تأیید براش ارسال میشه
  • تا زمانی که لینک رو نزنه، حسابش فعال نمیشه

📌 مراحل:

  1. ایجاد توکن فعال‌سازی
  2. ساخت URL
  3. ارسال ایمیل حاوی لینک
  4. ساخت view فعال‌سازی

۹. ایمیل بازیابی رمز عبور (Password Reset)

Django خودش سیستم آماده داره:

  • PasswordResetView
  • PasswordResetConfirmView

فقط لازمه قالب‌ها و تنظیمات ایمیل رو آماده کنیم.


۱۰. نکات امنیتی برای ارسال ایمیل

  1. اطلاعات SMTP رو در .env نگه دار (نه در کد اصلی)
  2. از TLS/SSL استفاده کن
  3. محدودیت Speed و تعداد ایمیل رعایت شه (SMTP ممکنه بلاک کنه)
  4. ایمیل‌های حساس رو حتماً رمزنگاری یا روی 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 جلوگیری شده

محمد وب‌سایت

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *