You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中实现草稿保存模块

Django 实现草稿保存功能方案

1. 扩展模型字段

给你的数据模型新增状态字段,用来区分草稿和已发送记录:

from django.db import models

class MailRecord(models.Model):
    # 原有业务字段
    title = models.CharField(max_length=255)
    content = models.TextField()
    attachment = models.FileField(upload_to='mail_attachments/', blank=True, null=True)
    # 新增状态标识字段
    STATUS_CHOICES = (
        ('draft', '草稿'),
        ('sent', '已发送'),
    )
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

2. 视图层处理草稿逻辑

在表单处理视图中,根据用户点击的按钮区分操作:

函数视图示例

from django.shortcuts import render, redirect
from .forms import MailRecordForm
from .models import MailRecord
from django.core.mail import EmailMessage

def mail_form(request):
    if request.method == 'POST':
        form = MailRecordForm(request.POST, request.FILES)
        if form.is_valid():
            record = form.save(commit=False)
            # 判断用户操作
            if 'save_draft' in request.POST:
                record.status = 'draft'
                record.save()
                return redirect('draft_list')
            elif 'send_mail' in request.POST:
                record.status = 'sent'
                record.save()
                # 执行邮件发送
                email = EmailMessage(
                    subject=record.title,
                    body=record.content,
                    from_email='your@domain.com',
                    to=['target@domain.com'],
                )
                if record.attachment:
                    email.attach_file(record.attachment.path)
                email.send()
                return redirect('send_success')
    else:
        # 加载草稿数据(编辑场景)
        draft_id = request.GET.get('draft_id')
        if draft_id:
            draft = MailRecord.objects.get(id=draft_id, status='draft')
            form = MailRecordForm(instance=draft)
        else:
            form = MailRecordForm()
    return render(request, 'mail_form.html', {'form': form})

类视图示例(FormView)

from django.views.generic.edit import FormView
from .forms import MailRecordForm
from .models import MailRecord
from django.core.mail import EmailMessage
from django.urls import reverse_lazy

class MailFormView(FormView):
    form_class = MailRecordForm
    template_name = 'mail_form.html'
    success_url = reverse_lazy('send_success')

    def get_initial(self):
        # 编辑草稿时填充初始值
        draft_id = self.request.GET.get('draft_id')
        if draft_id:
            draft = MailRecord.objects.get(id=draft_id, status='draft')
            return {
                'title': draft.title,
                'content': draft.content
            }
        return super().get_initial()

    def form_valid(self, form):
        record = form.save(commit=False)
        if 'save_draft' in self.request.POST:
            record.status = 'draft'
            record.save()
            self.success_url = reverse_lazy('draft_list')
            return super().form_valid(form)
        elif 'send_mail' in self.request.POST:
            record.status = 'sent'
            record.save()
            # 发送邮件
            email = EmailMessage(
                subject=record.title,
                body=record.content,
                from_email='your@domain.com',
                to=['target@domain.com'],
            )
            if record.attachment:
                email.attach_file(record.attachment.path)
            email.send()
            return super().form_valid(form)

3. 模板层添加操作按钮

在表单模板里设置两个提交按钮,分别对应保存草稿和发送:

<form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit" name="save_draft">保存草稿</button>
    <button type="submit" name="send_mail">发送邮件</button>
</form>

4. 草稿列表与编辑入口

新增视图展示所有草稿,支持编辑跳转:

from django.shortcuts import render
from .models import MailRecord

def draft_list(request):
    drafts = MailRecord.objects.filter(status='draft').order_by('-updated_at')
    return render(request, 'draft_list.html', {'drafts': drafts})

模板draft_list.html示例:

<h3>我的草稿</h3>
<ul>
    {% for draft in drafts %}
        <li>
            <a href="{% url 'mail_form' %}?draft_id={{ draft.id }}">{{ draft.title }}</a>
            <span>更新于: {{ draft.updated_at|date:"Y-m-d H:i" }}</span>
        </li>
    {% empty %}
        <li>暂无保存的草稿</li>
    {% endfor %}
</ul>

关键注意事项

  • 确保settings.py中正确配置MEDIA_ROOT和MEDIA_URL,保证附件文件正常存储和访问。
  • 多附件需求可通过创建关联模型(如Attachment)实现一对多存储。
  • 发送邮件前需在settings.py中配置邮件后端(如EMAIL_BACKEND、EMAIL_HOST等)。

内容的提问来源于stack exchange,提问作者Iron Man

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 04:27:27