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

为何Django在get_object_or_404生成的SQL中添加LIMIT 21?

Django查询自动添加LIMIT 21的原因

相关代码

模型

class Entity(models.Model):
    uuid = models.UUIDField(editable=False, unique=True, default=uuid.uuid4)
    institute_name = models.CharField(max_length=100, null=False)
    owner_name = models.CharField(max_length=100, null=False)
    contact_no = models.CharField(max_length=100, null=False)
    email_id = models.CharField(max_length=100, null=False, unique=True)
    # required fields for registration
    owner_password = models.CharField(max_length=100, null=True)
    address = models.CharField(max_length=200, default="")
    email_id_verified = models.BooleanField(default=False)
    phone_no_verified = models.BooleanField(default=False)
    registered_business = models.BooleanField(default=False)
    owner_id_details = models.JSONField(default=dict)
    registration_details = models.JSONField(default=dict)
    is_active = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

视图

获取实体详情的GET API:

class EntityDetailView(APIView):
    def get(self, request, id):
        entity = get_object_or_404(Entity, uuid=id)
        serializer = EntitySerializer(entity)
        return Response(serializer.data)

生成的SQL查询语句

SELECT "entities_entity"."id",
       "entities_entity"."uuid",
       "entities_entity"."institute_name",
       "entities_entity"."owner_name",
       "entities_entity"."contact_no",
       "entities_entity"."email_id",
       "entities_entity"."owner_password",
       "entities_entity"."address",
       "entities_entity"."email_id_verified",
       "entities_entity"."phone_no_verified",
       "entities_entity"."registered_business",
       "entities_entity"."owner_id_details",
       "entities_entity"."registration_details",
       "entities_entity"."is_active",
       "entities_entity"."created_at",
       "entities_entity"."updated_at"
  FROM "entities_entity"
 WHERE "entities_entity"."uuid" = '68e0956b-c166-4844-8842-51371c385a90'::uuid
 LIMIT 21

原因解释

这是Django内部的设计逻辑导致的:

  • get_object_or_404函数底层会先执行filter(...)[:1]获取匹配记录,而非直接调用get()——这么做是为了在数据库存在违反唯一约束的多条匹配数据时,能高效检测到并抛出MultipleObjectsReturned异常。
  • Django ORM处理切片[:1]时,默认生成LIMIT 21而非LIMIT 1。选择21是因为这个数值足够小,不会影响性能,同时能确保如果存在多条异常数据,查询结果数量会超过1,从而触发后续的异常判断逻辑。

内容的提问来源于stack exchange,提问作者Anshul-Dishoriya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 12:03:17