Django操作PostgreSQL时如何获取模型数组字段的元素数量
实现方案
核心逻辑是先读取目标记录的字段内容完成统计,再执行删除操作,不能直接链式调用删除方法,否则会丢失待统计的数据。
具体实现步骤
- 先查询出指定
user_id对应的记录,暂存到变量中,不直接执行删除 - 解析
vpa_upi_id字段存储的JSON格式字符串为Python原生列表 - 对列表求长度得到对应UPI总数量,如果是多条匹配记录则累加长度
- 完成统计后再执行删除操作
代码示例
由于模型中user_id字段设置了unique=True,最多只会匹配到1条记录,推荐写法如下:
import json from django.core.exceptions import ObjectDoesNotExist def delete_user_upi_record(user_id): upi_total = 0 try: # 先查询目标记录 upi_record = UserVpaUpiId.objects.get(user_id=user_id) # 解析JSON格式的vpa_upi_id内容 try: upi_items = json.loads(upi_record.vpa_upi_id) if isinstance(upi_items, list): upi_total = len(upi_items) except json.JSONDecodeError: # 遇到格式非法的脏数据时可自定义处理逻辑,此处默认按0计数 upi_total = 0 # 统计完成后执行删除 upi_record.delete() except ObjectDoesNotExist: # 不存在对应记录时计数为0 upi_total = 0 return upi_total
如果需要兼容可能存在多条匹配记录的场景,可以用filter批量查询的写法:
import json def batch_delete_user_upi_records(user_id): upi_total = 0 # 先获取匹配的记录集合 record_qs = UserVpaUpiId.objects.filter(user_id=user_id) # 遍历统计所有记录的UPI数量 for record in record_qs: try: upi_items = json.loads(record.vpa_upi_id) if isinstance(upi_items, list): upi_total += len(upi_items) except json.JSONDecodeError: continue # 统计完成后批量删除 record_qs.delete() return upi_total
注意事项
- 禁止直接写
UserVpaUpiId.objects.filter(user_id=user_id).delete()这种链式逻辑,查询结果会直接执行删除,无法读取字段内容做统计 vpa_upi_id是TextField类型,存的是序列化后的JSON字符串,必须转成Python列表后再统计长度,直接对字符串求len()得到的是字符个数,结果完全错误- 如果使用Django 3.1及以上版本,可以将
vpa_upi_id字段改为JSONField类型,ORM查询时会自动完成JSON解析,不需要手动调用json.loads(),代码会更简洁。
内容的提问来源于stack exchange,提问作者Meet Joshi
相关产品推荐
相关产品推荐

