Django模型使用UUID时调用latest('id')无法获取最新条目如何解决
Django UUID主键模型查询最新提交条目解决方案
问题根源
你使用的默认UUID(一般为UUIDv4)是完全随机的字符串,数值大小和条目提交时间没有关联,所以按id排序取最大的结果必然不是最新提交的条目。
正确实现方案
方案1:新增创建时间字段(最推荐,稳定性最高)
给Uploads模型新增自动记录插入时间的DateTimeField字段,无需手动赋值,插入数据时Django会自动填充:from django.db import models import uuid class Uploads(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) # 新增创建时间字段,auto_now_add 表示仅在实例首次创建时自动赋值为当前时间 created_at = models.DateTimeField(auto_now_add=True, db_index=True) # 其余原有字段保持不变执行
makemigrations和migrate完成数据库迁移后,使用如下语句即可获取最新提交的条目id:latest_id = Uploads.objects.latest('created_at').id高并发场景下如果存在多条数据同一时间插入的可能,可以调整为二级排序保证结果准确:
latest_id = Uploads.objects.latest('created_at', 'id').id方案2:使用时间有序UUID(无需新增字段)
将主键的UUID生成规则从随机UUIDv4替换为包含时间戳的有序UUID(推荐UUIDv7,避免UUIDv1泄露设备MAC地址的问题),有序UUID的数值大小和生成时间正相关,此时原有按id排序的逻辑可以正常运行:
调整后的模型字段示例:# 需先安装uuid6库实现UUIDv7:pip install uuid6 import uuid6 from django.db import models class Uploads(models.Model): id = models.UUIDField(primary_key=True, default=uuid6.uuid7, editable=False) # 其余原有字段保持不变调整后原有查询语句
Uploads.objects.latest('id')即可返回最新提交的条目。方案3:临时兼容方案(不推荐长期使用)
如果已经上线的业务不允许修改表结构,可以依赖数据库底层的隐藏自增行ID实现排序,该方法仅适配特定数据库,兼容性差:
以PostgreSQL为例:latest_id = Uploads.objects.extra(select={'rowid': 'ctid'}).order_by('-rowid').first().idMySQL使用
_rowid替代ctid即可。
内容的提问来源于stack exchange,提问作者Rihab sabri
相关产品推荐
相关产品推荐

