需求分析
想建立一张电子邮件表, 当往表里面写一行记录的时候, 自动发邮件, 邮件的配置就是表里的内容.
方案
发邮件本身, 可以使用django-email来实现. 然后定义信号函数, 当表被save的时候自动发邮件. 然后通过xadmin做管理
code
settings.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.partner.outlook.cn'
EMAIL_PORT = 25
EMAIL_HOST_USER = 'xxx'
EMAIL_HOST_PASSWORD = 'xxx'
DEFAULT_FROM_EMAIL = 'xxx'
utils/django_email.py
# -*- coding: utf-8 -*-
__author__ = '陈章'
__date__ = '2019/9/9 15:22'
import os
import sys
pwd = os.path.dirname(os.path.realpath(__file__))
sys.path.append(pwd + '/../')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xxx_xadmin.settings")
import django
django.setup()
from django.conf import settings
from django.core.mail import EmailMultiAlternatives
def send_email(to_addr, subject, content, attachments=None):
if attachments is None:
attachments = []
if not isinstance(to_addr, list):
to_addr = [to_addr]
from_email = settings.DEFAULT_FROM_EMAIL
msg = EmailMultiAlternatives(subject, content, from_email, to_addr)
msg.content_subtype = "html"
# 添加附件(可选)
for a in attachments:
msg.attach_file(a)
# 发送
msg.send()
if __name__ == '__main__':
send_email("chenzhang@xxx.cn", "测试", "啪啪啪",
attachments=["~/xxx_xadmin/utils/django_email.py",
'~/xxx_xadmin/utils/exceptions.py'])
models.py
# -*- coding: utf-8 -*-
__author__ = '陈章'
__date__ = '2019/9/9 15:00'
from django.contrib.postgres.fields import ArrayField
from django.db import models
from DjangoUeditor.models import UEditorField
from xxx_xadmin.settings import DEFAULT_FROM_EMAIL
class Email(models.Model):
STATUS_CHOICES = (('发送中', '发送中'), ('发送完成', '发送完成'), ('发送失败', '发送失败'))
sender = models.EmailField(help_text='发件人', default=DEFAULT_FROM_EMAIL)
receivers = ArrayField(models.EmailField(), help_text='收件人(多个用逗号隔开)')
subject = models.CharField(max_length=200, help_text='邮件主题')
content = UEditorField(help_text="内容", imagePath="emails/content_img", width=1000, height=300,
filePath="emails/content_files", default='')
status = models.CharField(max_length=100, choices=STATUS_CHOICES, default='发送中', help_text=f'发送状态 {STATUS_CHOICES}')
fail_reason = models.TextField(help_text='失败原因', default='')
attachments_path_list = ArrayField(models.FilePathField(), verbose_name='附件路径列表')
update_time = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = '电子邮件'
verbose_name_plural = verbose_name
def attachment_count(self):
return len(self.attachments_path_list)
signals.py
# -*- coding: utf-8 -*-
__author__ = '陈章'
__date__ = '2019/9/9 19:47'
from django.dispatch import receiver
from django.db.models.signals import post_save
from .models import Email
import traceback
@receiver(post_save, sender=Email)
def send_emails_after_save(sender, instance=None, created=False, **kwargs):
from utils.django_email import send_email
if created:
attachments_path_list = instance.attachments_path_list
try:
send_email(instance.receivers, instance.subject, instance.content,
attachments_path_list)
except Exception as e:
instance.status = '发送失败'
instance.fail_reason = traceback.format_exc()
else:
instance.status = '发送完成'
instance.save()
apps.py
# -*- coding: utf-8 -*-
__author__ = '陈章'
__date__ = '2019/9/9 19:53'
from django.apps.config import AppConfig
class EmailsConfig(AppConfig):
name = 'emails'
verbose_name = '电子邮件'
def ready(self):
from emails import signals
id(signals)
adminx.py
# -*- coding: utf-8 -*-
__author__ = '陈章'
__date__ = '2019/9/9 16:20'
import xadmin
from .models import Email
class EmailAdmin:
list_display = ["sender", "receivers", "subject", "content", "status", "update_time", 'attachment_count']
exclude = ["status", "update_time", ]
remove_permissions = ('change',)
style_fields = {"content": "ueditor"}
xadmin.site.register(Email, EmailAdmin)