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

Django实现同表sessions字段加10存入totalsessions字段方法

核心问题

现有代码存在3个明显问题导致需求无法实现:

  • 仅对sessions字段做了累加赋值,完全没有编写totalsessions的赋值逻辑,该字段自然不会更新持久化
  • 先手动修改实例调用save(),再绑定request.data做序列化校验的逻辑冗余,还可能被前端传入的非法值覆盖计算好的sessions数值
  • 序列化器未显式包含totalsessions字段时,返回结果不会携带该字段值,前端无法拿到数据渲染表格
修改方案

1. 重写视图逻辑(views.py)

用数据库原子累加避免并发计算错误,去掉冗余的序列化校验逻辑,同时更新两个字段:

from django.db.models import F
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import JsonResponse
from django.shortcuts import get_object_or_404
from .models import Swimmers
from .serializers import SubSerializer

@api_view(['POST'])
def swimmersReduce(request, pk):
    # 校验对应游泳者实例存在
    sw = get_object_or_404(Swimmers, id=pk)
    
    # 数据库层面原子更新两个字段,避免并发场景下数值累加错误
    # F表达式直接在数据库侧取值计算,不需要先把数据读到内存
    Swimmers.objects.filter(id=pk).update(
        sessions=F('sessions') + 10,
        totalsessions=F('sessions') + 10
    )
    
    # 刷新内存中实例的字段值,拿到最新的计算结果
    sw.refresh_from_db()
    
    # 直接序列化最新实例返回,不需要接收前端传值校验,避免非法数据覆盖
    serializer = SubSerializer(instance=sw)
    return JsonResponse(serializer.data, safe=False, status=status.HTTP_200_OK)

注:你提到的「点击按钮后前端表格新增一行」属于前端逻辑,后端只需要返回更新后的完整字段值即可,前端拿到返回的totalsessions后直接追加表格行即可,不需要后端在Swimmers表新增记录。

2. 检查序列化器配置

确认SubSerializer的字段列表包含totalsessions,否则返回结果不会携带该字段:

from rest_framework import serializers
from .models import Swimmers

class SubSerializer(serializers.ModelSerializer):
    class Meta:
        model = Swimmers
        fields = [
            'id', 'name', 'lastname', 'idno', 
            'sessions', 'totalsessions', 'dateofpayment'
        ]

3. (可选)模型层自动同步字段

如果项目里还有其他地方会更新sessions字段,可以重写模型的save方法,自动同步sessions值到totalsessions,避免漏更:

from django.db import models

class Swimmers(models.Model):
    name = models.CharField(max_length=200, blank=False)
    lastname = models.CharField(max_length=200, blank=False)
    idno = models.CharField(max_length=200, blank=False, null=True)
    sessions = models.IntegerField(blank=False)
    totalsessions = models.IntegerField(blank=True, null=True)
    dateofpayment = models.CharField(max_length=200, blank=True)

    def save(self, *args, **kwargs):
        # sessions赋值时自动同步到totalsessions
        if self.sessions is not None:
            self.totalsessions = self.sessions
        super().save(*args, **kwargs)

添加该逻辑后,视图层不需要再手动写totalsessions的更新逻辑,只要sessions变更,save时会自动同步。

注意事项
  • 不要在内存中读取实例字段值计算后再保存,高并发场景下会出现多个请求读到同一个旧值,导致累加结果错误,用F()表达式可以完全避免这个问题
  • 该接口的逻辑是固定累加10,不需要前端传入任何业务字段,不要把request.data传给序列化器校验,防止前端伪造字段值篡改数据
  • 接口返回200状态码即可,原代码用201状态码不符合REST规范,201用于资源创建场景,该接口是更新操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:48:25