如何基于Django表单实现固定收件人、可变发件人的邮件发送
实现固定收件人、仅可变更发件人的邮件发送功能
首先得先修正你Model里的几个小问题:
- 你在Model里用了
forms.CharField定义password,这是不对的——Model字段得用models.CharField,密码输入框的配置应该放在表单类里做,不是Model层面。 - 如果收件人要固定,其实完全不用在Model里存
email1,直接在视图里写死,或者放到配置文件里更灵活。
接下来一步步实现:
1. 修正并调整Model
我们只保留需要的字段,收件人固定就不用存进Model了,重点保留发件人相关的邮箱和授权码(注意:这里的密码一般是邮箱的SMTP授权码,不是普通登录密码):
from django.db import models # 补充你没写完的颜色选项示例 COLOR_CHOICES = [ ('ff0000', '红色'), ('00ff00', '绿色'), ('0000ff', '蓝色'), ] class ContactModel(models.Model): fullname = models.CharField(max_length=20, null=True, blank=True) email = models.EmailField(null=True, blank=True) # 发件人邮箱 password = models.CharField(max_length=100) # 发件邮箱的SMTP授权码/密码 subject = models.CharField(max_length=30, null=True, blank=True) message = models.TextField(max_length=200) color = models.CharField(max_length=6, choices=COLOR_CHOICES, null=True, blank=True) def __str__(self): return self.fullname or self.email
2. 创建表单类(forms.py)
这里我们要完全隐藏收件人相关字段,只让用户输入发件人信息和邮件内容:
from django import forms from .models import ContactModel class ContactForm(forms.ModelForm): # 在这里给密码字段加上密码输入框的样式 password = forms.CharField(widget=forms.PasswordInput()) class Meta: model = ContactModel # 只展示需要用户输入的字段,排除收件人 fields = ['fullname', 'email', 'password', 'subject', 'message', 'color']
3. 编写视图处理邮件发送(views.py)
在视图里写死固定收件人,然后用Django的EmailMessage来处理邮件发送,同时配置动态的发件人SMTP信息:
from django.shortcuts import render, redirect from django.core.mail import EmailMessage from .forms import ContactForm # 固定收件人,也可以放到settings.py里统一管理,比如settings.FIXED_RECIPIENT = 'xxx@example.com' FIXED_RECIPIENT = 'your-fixed-email@example.com' def send_email(request): if request.method == 'POST': form = ContactForm(request.POST) if form.is_valid(): contact = form.save() # 构建邮件对象 email = EmailMessage( subject=contact.subject, body=contact.message, from_email=contact.email, to=[FIXED_RECIPIENT], # 这里就是固定的收件人 reply_to=[contact.email] # 让收件人回复时直接回到发件人邮箱 ) # 配置对应发件邮箱的SMTP信息,不同邮箱参数不一样 email.connection = email.get_connection( host='smtp.example.com', # 比如QQ邮箱是smtp.qq.com,163邮箱是smtp.163.com port=587, # 一般是587(TLS)或465(SSL) username=contact.email, password=contact.password, use_tls=True # 开启TLS加密,大部分邮箱需要 ) try: email.send() return redirect('success_page') # 发送成功后跳转页面 except Exception as e: # 发送失败时给用户提示错误 form.add_error(None, f"邮件发送失败:{str(e)}") else: form = ContactForm() return render(request, 'contact_form.html', {'form': form})
4. 模板文件(templates/contact_form.html)
渲染表单给用户填写:
<form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">发送邮件</button> </form> {% if form.non_field_errors %} <div style="color: red; margin-top: 10px;">{{ form.non_field_errors }}</div> {% endif %}
几个重要注意事项
- 发件邮箱必须开启SMTP服务,并且要用授权码代替登录密码(比如QQ邮箱、163邮箱都需要在账号设置里单独生成授权码)。
- 为了安全,不要明文存储用户输入的密码,建议用加密算法存储,发送邮件时再解密。
- 可以额外添加表单验证,比如校验发件邮箱的格式是否符合对应SMTP服务商要求,或者添加验证码防止邮件滥用。
内容的提问来源于stack exchange,提问作者Sunny Prakash
相关产品推荐
相关产品推荐

