基于Django实现学生注册信息PDF生成并邮件附件发送的技术咨询
嘿,这个需求我前段时间刚在Django项目里实现过,完全能搞定!核心思路是先把用户信息通过Django模板渲染成HTML,再转成PDF字节流(不用存本地文件,直接放内存里),最后作为邮件附件发送给用户。下面是一步步的具体实现:
解决方案步骤
1. 准备依赖:安装WeasyPrint
它能直接把HTML(包括Django模板渲染后的内容)转成PDF,比ReportLab更适配模板化的场景,用起来更省心。
pip install weasyprint
注:Linux系统可能需要先装系统依赖,比如apt-get install libpango-1.0-0 libcairo2 libgdk-pixbuf2.0-0;Mac可以用Homebrew安装对应包
2. 编写生成PDF的工具函数
这个函数负责渲染模板、把用户信息转成内存中的PDF字节流:
from django.template.loader import render_to_string from weasyprint import HTML import io def generate_student_pdf(student_data): # 用Django模板渲染用户信息成HTML html_content = render_to_string('student_registration/student_pdf_template.html', {'student': student_data}) # 将HTML转成PDF,输出到内存字节流 pdf_file = io.BytesIO() HTML(string=html_content).write_pdf(pdf_file) # 将文件指针移到开头,方便后续读取 pdf_file.seek(0) return pdf_file
3. 编写PDF展示模板
创建一个普通的Django模板student_registration/student_pdf_template.html,用来格式化展示用户注册信息:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>学生注册确认单</title> <style> body { font-family: Arial, sans-serif; margin: 2rem; } .info-card { margin: 2rem 0; padding: 1.5rem; border: 1px solid #eee; border-radius: 8px; } h1 { color: #2d3748; text-align: center; } .field-item { margin: 0.8rem 0; font-size: 1.1rem; } .field-label { font-weight: 600; color: #4a5568; } </style> </head> <body> <h1>学生注册确认通知</h1> <div class="info-card"> <div class="field-item"><span class="field-label">姓名:</span>{{ student.name }}</div> <div class="field-item"><span class="field-label">学号:</span>{{ student.student_id }}</div> <div class="field-item"><span class="field-label">邮箱:</span>{{ student.email }}</div> <div class="field-item"><span class="field-label">专业:</span>{{ student.major }}</div> <!-- 按需添加其他注册字段 --> </div> </body> </html>
4. 在表单处理视图中整合PDF生成与邮件发送
在你已经写好的表单提交视图里,加入生成PDF和发送邮件的逻辑:
from django.core.mail import EmailMessage from django.shortcuts import render, redirect from .forms import StudentRegistrationForm from .models import Student from .utils import generate_student_pdf # 导入刚才写的工具函数 def student_registration(request): if request.method == 'POST': form = StudentRegistrationForm(request.POST) if form.is_valid(): # 保存用户注册信息到数据库 student = form.save() # 生成用户专属的PDF字节流 pdf_file = generate_student_pdf(student) # 构建邮件内容 email = EmailMessage( subject='你的学生注册确认单已生成', body='您好,附件是你的注册信息确认PDF,请查收保存。', from_email='school-reg@example.com', to=[student.email], ) # 添加PDF附件 email.attach('student_reg_confirm.pdf', pdf_file.read(), 'application/pdf') # 发送邮件 email.send() # 跳转到注册成功页面 return redirect('registration_success') else: form = StudentRegistrationForm() return render(request, 'student_registration/registration_form.html', {'form': form})
5. 配置Django邮件发送参数
在settings.py里配置邮件服务,比如用SMTP:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.example.com' # 比如smtp.gmail.com、smtp.qq.com EMAIL_PORT = 587 EMAIL_USE_TLS = True EMAIL_HOST_USER = 'your-email@example.com' EMAIL_HOST_PASSWORD = 'your-email-auth-code' # 注意:第三方邮箱可能需要用应用专用密码
调试小技巧
- 测试阶段可以把
EMAIL_BACKEND改成django.core.mail.backends.console.EmailBackend,这样邮件内容会直接输出到控制台,不用真的发送,方便调试。 - 如果模板里有静态资源(比如学校logo),要给WeasyPrint指定
base_url参数:HTML(string=html_content, base_url=request.build_absolute_uri()).write_pdf(pdf_file),确保资源能被正确加载。
内容的提问来源于stack exchange,提问作者Mic
相关产品推荐
相关产品推荐

