为何Django中first()方法与切片查询返回结果不同?
Django中
PhotoAlbum.objects.all().first()和[:1].get()返回不同对象的原因 定义的模型代码
class PhotoAlbum(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, auto_created=True) name = models.CharField(max_length=50, verbose_name='Album name') type = models.ForeignKey(AlbumType, on_delete=models.CASCADE, verbose_name='Album type') created_at = models.DateTimeField(auto_now_add=True)
测试代码
print(PhotoAlbum.objects.all().first()) print(PhotoAlbum.objects.all()[:1].get())
原因解析
核心问题出在没有指定明确的排序规则:
first()方法会自动给QuerySet添加基于主键的排序逻辑(你的主键是UUID,生成时是随机值),再返回排序后的第一条数据。[:1].get()是先对未排序的QuerySet做切片,此时数据库返回的结果顺序完全由数据库自身的存储/检索策略决定(没有固定顺序),再取出唯一的对象。
因为两次查询的排序逻辑不一致,所以大概率会返回不同的对象。
解决办法
给QuerySet指定统一的排序规则即可:
- 直接在查询时添加排序
# 按创建时间排序,也可以换成'id' sorted_queryset = PhotoAlbum.objects.all().order_by('created_at') print(sorted_queryset.first()) print(sorted_queryset[:1].get())
- 在模型Meta类中设置默认排序
class PhotoAlbum(models.Model): # 现有字段... class Meta: ordering = ['created_at'] # 全局默认按创建时间排序
内容的提问来源于stack exchange,提问作者Anonymous Wizard
相关产品推荐
相关产品推荐

