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

Django搭配PostgreSQL时如何向模型ArrayField追加数据值

问题根因

代码存在两个致命错误,直接导致ArrayField写入、追加失败:

  • Python列表的append()是原地修改方法,执行后不会返回新列表,返回值固定为None。执行attend.time = attend.time.append(xxx)的逻辑,本质是把time字段直接赋值为None,原有数据会被直接清空。
  • 通过get_or_create生成新记录时,time字段默认值是*NULL(模型配置了null=True),直接对None调用append()会触发NoneType属性错误*,新记录根本无法正常写入。
基础修复方案

调整逻辑:新建记录时提前把time字段初始化为空列表,追加值时不要接收append()的返回值,直接修改列表后保存即可。
修正后的视图代码:

attend, created = models.AttendanceModel.objects.get_or_create(
    user=fingerprint.user,
    date=attendance_date,
    # 新建记录时直接初始化time为空列表,避免操作None值
    defaults={'time': []}
)

# 直接在原有列表上追加值,不要重新赋值append的返回结果
attend.time.append(attendance.timestamp.time())
attend.save()
并发场景优化方案

如果存在同一用户同一日期多条打卡数据并发写入的场景,上面的先查后改逻辑会出现竞态条件:读取旧列表到内存、追加值、保存的间隙如果有其他请求也修改了该字段,会导致中间写入的数据丢失。这种场景可以用Django内置的ArrayAppend函数,直接在数据库层面完成数组追加,不需要提前读取字段值:

from django.contrib.postgres.functions import ArrayAppend

# 单条语句完成存在则更新、不存在则创建+追加的逻辑,避免并发冲突
obj, created = models.AttendanceModel.objects.update_or_create(
    user=fingerprint.user,
    date=attendance_date,
    defaults={'time': []}
)
# 数据库层面执行数组追加
obj.time = ArrayAppend('time', attendance.timestamp.time())
obj.save()

注意:使用数据库层面追加方案时,必须保留defaults里的空列表初始化配置,否则对NULL值执行数组追加操作会抛出数据库错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 23:09:15