Django开发SMTP邮件工具出现CharField无encode属性报错求解
问题根因
- 你调用
send_mail()方法时仅传递了auth_password参数,未传递auth_user参数,Django默认会读取settings.py中配置的EMAIL_HOST_USER作为SMTP登录用户名。如果该项配置为空、或者配置错误指向了表单字段对象,就会导致SMTP登录时拿到的是CharField类型而非字符串,调用encode方法时报错。 - 额外注意:你
form_valid方法的参数名和表单类名ToolsForm重名,虽然不会直接导致本次报错,但容易引发作用域混淆问题,建议修改为通用的form命名。 - 表单中邮箱字段用
CharField虽然搭配EmailInput也能用,但直接用EmailField可以自动做邮箱格式校验,减少非法输入问题。
修复步骤
1. 修改Forms.py中的send_email方法,补全auth_user参数
将send_mail调用行修改为以下内容,显式指定SMTP登录用户为发件人邮箱:
send_mail(subject, message, sender, [receiver], auth_user=sender, auth_password=password, fail_silently=False)
2. 可选优化:调整form_valid参数名避免命名冲突
修改Views.py中的form_valid方法,修正参数命名:
def form_valid(self, form): ''' 表单数据校验通过后触发该方法 ''' form.send_email() return super().form_valid(form)
3. 可选优化:将邮箱字段改为EmailField增强校验
把Forms.py中两个邮箱字段的定义替换为EmailField,自动做格式校验:
sender_mail = forms.EmailField(required=True, widget=forms.EmailInput(attrs={'placeholder': '请输入发件人邮箱账号:'})) receiver_mail = forms.EmailField(required=True, widget=forms.EmailInput(attrs={'placeholder': '请输入收件人邮箱账号:'}))
4. 配置确认
检查settings.py中是否配置了正确的SMTP基础参数,以下是参考配置:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.qq.com' # 替换为对应邮箱的SMTP服务器地址 EMAIL_PORT = 587 # 常见SMTP端口为587或465 EMAIL_USE_TLS = True # 绝大多数公共邮箱要求开启TLS加密
如果不想每次在表单填写发件人账号密码,也可以直接在settings中配置全局的EMAIL_HOST_USER和EMAIL_HOST_PASSWORD,调用send_mail时就不需要单独传auth_user和auth_password参数。
内容的提问来源于stack exchange,提问作者Precious Chika
相关产品推荐
相关产品推荐

