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

Django中表单提交数据高效保存与更新的实现方案

方案优化思路与实现

核心调整前提

由于原有提交逻辑仅上传文本内容,无法区分内容对应的数据库记录,首先需要前端配合做小调整:

  • 渲染预填充表单时,为每个已存在的Sentence记录对应的输入框绑定原数据库主键id
  • 提交时每条内容需附带对应的id值,新增的内容id统一传0或空字符串做标识
    可以选择两种提交方式:两个索引一一对应的列表sentence_ids、sentence_contents,或者直接传结构化JSON列表,每个元素包含id和content字段。

后端优化逻辑

核心是避免全量删改,仅做增量操作,同时用Django批量操作接口减少数据库交互次数:

  1. 先拉取当前用户所有存量数据,用id做索引存入字典,降低查询开销
  2. 对比提交数据和存量数据,拆分出「待删除」「待更新」「待新增」三类数据
  3. 分别对三类数据做批量操作,无变更时直接跳过所有数据库操作
  4. 增加事务保证操作原子性,避免中途出错导致数据异常

优化后代码实现

from .models import Sentence
from django.db import transaction

def index(request):
    if request.method == "POST" and request.user.is_authenticated:
        # 前端提交两个对应索引的列表:id列表和内容列表
        sentence_ids = request.POST.getlist("sentence_id")
        sentence_contents = request.POST.getlist("sentence_content")

        # 开启事务保证所有操作原子性
        with transaction.atomic():
            # 1. 拉取当前用户所有存量数据,构建id到记录的映射
            existing_sentences = Sentence.objects.filter(user=request.user).in_bulk()
            existing_ids = set(existing_sentences.keys())

            submitted_valid_ids = set()
            to_update = []
            to_create = []

            # 2. 遍历提交数据拆分待更新、待新增记录
            for sid, content in zip(sentence_ids, sentence_contents):
                # 可根据业务需求决定是否过滤空内容
                if not content.strip():
                    continue
                try:
                    record_id = int(sid)
                except (ValueError, TypeError):
                    record_id = 0

                if record_id > 0 and record_id in existing_ids:
                    # 已有记录,对比内容判断是否需要更新
                    submitted_valid_ids.add(record_id)
                    if existing_sentences[record_id].sentence != content:
                        existing_sentences[record_id].sentence = content
                        to_update.append(existing_sentences[record_id])
                else:
                    # 新增记录暂存
                    to_create.append(Sentence(user=request.user, sentence=content))

            # 3. 批量删除:存量id不在提交的有效id范围内的记录
            to_delete_ids = existing_ids - submitted_valid_ids
            if to_delete_ids:
                Sentence.objects.filter(id__in=to_delete_ids).delete()

            # 4. 批量更新内容有变更的记录
            if to_update:
                Sentence.objects.bulk_update(to_update, ['sentence'])

            # 5. 批量新增记录
            if to_create:
                Sentence.objects.bulk_create(to_create)

    # 其他原有代码

优化效果说明

完全适配四种提交场景,性能提升明显:

  • 用户仅编辑部分已有字段:仅批量更新变更的记录,无额外开销
  • 用户新增部分字段:仅批量插入新增记录
  • 用户删除部分已有字段:仅批量删除被移除的记录
  • 用户未做任何修改:所有数据库操作全部跳过,零开销

原有实现需要N+1次数据库交互(1次全量删除+N次单条插入),优化后最多只有3次数据库操作,数据量越大性能优势越显著。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 00:27:03