如何解决Django结合PythonAnywhere任务调度器发送定时邮件的问题?
问题分析与解决方案
让我一步步帮你拆解并解决这些问题:
1. 错误的异常捕获逻辑
你当前的try-except块逻辑完全误导了你:当今天是周三时进入try块,不管邮件发送是否成功,只要出现任何异常都会打印"It is not Wednesday"——但实际异常大概率是邮件配置或Django环境初始化的问题,和日期无关。比如Django环境没配置好导致发送邮件失败时,就会错误触发这个提示,让你误以为日期判断出错,但其实weekday == 2的判断是正确的(Python中weekday()返回2代表周三)。
2. RecursionError的根源
settings.configure(settings, DEBUG=True)这行代码是核心错误:你把Django的settings对象本身作为参数传给了configure方法,导致递归引用,直接触发了最大递归深度超限的错误。configure方法需要传入的是具体的配置键值对,而非settings对象本身。
3. Django环境未正确初始化
单独运行脚本时,Django不知道要加载哪个项目的settings模块,所以不能直接调用send_mail,必须先完成Django环境的初始化。
修正后的完整代码
下面是调整后的代码,解决了所有问题:
import os import datetime # 第一步:设置Django的settings模块环境变量 # 替换成你的实际项目名称,比如你的项目叫MPSA,就写"MPSA.settings" os.environ.setdefault("DJANGO_SETTINGS_MODULE", "你的项目名称.settings") # 初始化Django环境 import django django.setup() from django.core.mail import send_mail from django.conf import settings today = datetime.date.today() weekday = today.weekday() subject = 'New weekly email' message = 'Hi there!' # 先判断是否是周三,再处理邮件发送逻辑 if weekday == 2: print("今天是周三,准备发送邮件...") try: send_mail( subject, # 使用定义好的主题变量 message, # 使用定义好的内容变量 settings.EMAIL_HOST_USER, # 直接复用settings里的发件人配置,避免硬编码 ['to@gmail.com'], # 替换成你的收件人邮箱 fail_silently=False, ) print('邮件发送成功!') except Exception as e: # 捕获具体异常并打印,方便排查问题 print(f"邮件发送失败,错误信息:{str(e)}") else: print(f"今天是{today.strftime('%A')},不需要发送邮件")
关键调整说明
- 正确初始化Django环境:通过设置
DJANGO_SETTINGS_MODULE环境变量+调用django.setup(),让脚本能正确加载你项目的settings配置,彻底解决ImproperlyConfigured错误。 - 修复异常捕获逻辑:把日期判断放在try块外,try块只处理邮件发送的异常,同时捕获具体异常信息,方便你排查邮件发送的真实问题(比如SMTP配置错误、网络问题等)。
- 避免硬编码:直接使用
settings.EMAIL_HOST_USER作为发件人,和项目配置保持一致,不用手动重复写邮箱地址。 - 移除错误的configure调用:不需要手动调用
settings.configure,因为我们已经通过加载项目settings获取了所有配置。
PythonAnywhere任务调度器配置注意事项
在PA设置定时任务时,记得:
- 填写脚本的完整路径,比如
/home/你的PA用户名/你的项目目录/weeklyemailmm.py - 选择和你项目一致的Python版本
- 先在PA控制台手动运行一次脚本,确认无错误后再添加定时任务
内容的提问来源于stack exchange,提问作者RlM
相关产品推荐
相关产品推荐

