使用Cookiecutter-django时,如何让django-allauth发送HTML邮件?
我之前也碰到过一模一样的情况——明明放了HTML模板,却只收到纯文本邮件,下面是几个你需要逐一排查的关键点:
1. 确认HTML模板的命名和位置完全正确
django-allauth对邮件模板的命名有严格要求,HTML模板必须和对应纯文本模板同名但后缀为.html。比如:
- 注册确认邮件的纯文本模板默认是
email_confirmation_signup.txt(如果没自定义,用的是allauth自带的) - 你的HTML模板必须命名为
email_confirmation_signup.html,并且放在项目根目录的templates/account/文件夹下
如果文件名不匹配,allauth会直接忽略HTML模板,只发送纯文本版本。
2. 检查Django的模板配置是否能识别你的自定义模板
打开settings.py,确认TEMPLATES配置里的DIRS包含了你的templates目录:
TEMPLATES = [ { # ... 其他配置项 'DIRS': [BASE_DIR / 'templates'], # 确保这一行存在 'APP_DIRS': True, # ... } ]
如果DIRS没设置,Django只会去各个app的templates目录找模板,你的项目级templates/account就不会被识别。
3. 验证django-anymail的后端配置是否正确
确保你已经正确配置了mailgun作为邮件后端,settings.py里的相关配置应该类似这样:
EMAIL_BACKEND = 'anymail.backends.mailgun.EmailBackend' ANYMAIL = { 'MAILGUN_API_KEY': '你的Mailgun API密钥', 'MAILGUN_SENDER_DOMAIN': '你的Mailgun域名', } DEFAULT_FROM_EMAIL = '你的发件邮箱 <no-reply@your-domain.com>'
如果EMAIL_BACKEND还是默认的django.core.mail.backends.smtp.EmailBackend,即使有HTML模板,也可能因为后端问题无法发送multipart邮件。
4. 排查HTML模板是否有渲染错误
如果你的HTML模板里有语法错误(比如变量拼写错误、模板标签使用不当),django-allauth在渲染时会失败,自动 fallback到纯文本模板。你可以在Django shell里手动测试渲染:
# 进入Django shell python manage.py shell # 导入必要模块 from django.template.loader import render_to_string from django.contrib.auth.models import User from allauth.account.models import EmailConfirmation # 获取测试用户和确认对象(没有的话可以先创建一个) user = User.objects.first() confirmation = EmailConfirmation.objects.filter(user=user).first() # 尝试渲染HTML模板 try: html_content = render_to_string('account/email_confirmation_signup.html', { 'user': user, 'confirmation': confirmation, 'request': None # 如果模板用到request可以传测试request }) print(html_content) except Exception as e: print(f"模板渲染错误: {e}")
如果这里抛出错误,就需要修复HTML模板里的问题。
5. 检查是否自定义了AccountAdapter
如果你在settings.py里设置了ACCOUNT_ADAPTER为自定义适配器,要确保你没有重写send_confirmation_mail方法,或者重写时正确处理了HTML模板。比如自定义适配器应该调用父类的方法:
from allauth.account.adapter import DefaultAccountAdapter class CustomAccountAdapter(DefaultAccountAdapter): def send_confirmation_mail(self, request, emailconfirmation, signup): # 自定义逻辑写在这里,最后调用父类方法 super().send_confirmation_mail(request, emailconfirmation, signup)
如果完全重写了这个方法却没处理HTML模板的加载,就只会发送纯文本邮件。
按照上面的步骤排查下来,应该就能解决HTML邮件不发送的问题了。
内容的提问来源于stack exchange,提问作者Brad Rhoads

