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

Django更新模型字段时如何向指定列追加数据而非覆盖原有内容

Django 表单更新时追加字段数据实现方案

先修复现有代码的显性问题

你现有代码存在几处书写错误,会导致逻辑无法正常运行,先做修正:

models.py 修正

  • 移除current_commands字段定义末尾多余的逗号,该逗号会导致字段被识别为元组而非模型字段
  • 给Executed_Commands设置默认空字符串,避免首次操作时取到None触发拼接错误
CHOICES = [
    ('Sleep', "Sleep"),
    ('Open SSH_Tunnel', 'Open SSH_Tunnel'),
    ('Close SSH_Tunnel', 'Close SSH_Tunnel'),
    ('Open TCP_Tunnel', 'Open TCP_Tunnel'),
    ('Close TCP_Tunnel', 'Close TCP_Tunnel'),
    ('Open Dynamic', 'Open Dynamic'),
    ('Close Dynamic', 'Close Dynamic'),
    ('Task', 'Task'),
]


class Command_Node(models.Model):
    host_id = models.ForeignKey(Beacon, on_delete=models.CASCADE)
    current_commands = models.CharField(choices=CHOICES, max_length=50, null=True)
    Executed_Commands = models.CharField('Executed_Commands', max_length=2000, null=True, default="")
    
    def __str__(self):
        return str(self.host_id)

forms.py 修正

  • 自定义字段必须写在Meta类外部,写在内部不会生效
  • 修正current_comamnds的拼写错误为current_commands
class Command_Form(ModelForm):
    host_id = forms.ModelChoiceField(
        required=True,
        queryset=Beacon.objects.all(),
        widget=forms.SelectMultiple(
            attrs={
                'class': 'form-control'
            },
        )
    )
    current_commands = forms.ChoiceField(
        required=True,
        choices=CHOICES
    )

    class Meta:
        model = Command_Node
        fields = (
            'host_id',
            'current_commands'
        )

修改视图实现历史命令追加逻辑

核心思路是表单校验通过后,不直接执行form.save()写入数据库,而是先通过commit=False拿到暂存的模型实例,将本次提交的新命令追加到Executed_Commands字段后再执行保存,不会覆盖原有历史数据。
这里用换行符\n分隔不同历史命令,方便后续读取时拆分展示。

def update(request, host_id):
    host_obj = Command_Node.objects.get(pk=host_id)
    form = Command_Form(request.POST or None, instance=host_obj)
    if form.is_valid():
        # 暂存实例,不立即写入数据库
        instance = form.save(commit=False)
        new_command = instance.current_commands
        # 追加历史命令,空值时不加分隔符避免开头空行
        if instance.Executed_Commands:
            instance.Executed_Commands = f"{instance.Executed_Commands}\n{new_command}"
        else:
            instance.Executed_Commands = new_command
        # 最终写入数据库
        instance.save()
        return redirect('home')
    
    return render (request, 'update.html', {'host_id':host_obj,'form':form})

可选优化方案

如果你的Django版本 >= 3.1,建议将Executed_Commands替换为内置的JSONField,直接存储命令列表,不需要手动处理字符串分隔,也不会出现CharField长度溢出的问题,后续查询、统计历史命令更方便:

  1. 模型修改:
from django.db import models
# 其他代码不变
class Command_Node(models.Model):
    host_id = models.ForeignKey(Beacon, on_delete=models.CASCADE)
    current_commands = models.CharField(choices=CHOICES, max_length=50, null=True)
    # 用JSONField存列表,默认空列表
    Executed_Commands = models.JSONField(default=list)
    
    def __str__(self):
        return str(self.host_id)
  1. 视图追加逻辑修改:
if form.is_valid():
    instance = form.save(commit=False)
    new_command = instance.current_commands
    # 直接向列表追加元素即可
    instance.Executed_Commands.append(new_command)
    instance.save()
    return redirect('home')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 16:39:19