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

Django+React花瓶检索项目REST API URL参数查询部分有效值失效

异常根因分析

1. 核心问题:全局异常捕获吞掉了查询错误

你的代码中对关联表查询用了裸except语句,会捕获所有类型的异常并直接跳过过滤逻辑,最终返回初始的全量数据集。触发异常的常见场景有两个:

  • 关联表(Shape/Provenance/Collection/Artist)存在shapeName/provenanceName等名称字段重复的记录,调用objects.get()查询时会抛出MultipleObjectsReturned异常,直接被捕获后跳过过滤
  • 少数情况下URL参数传递时存在编码问题(比如特殊字符、空格未正确转义),导致参数值和数据库存储的值不一致,get()抛出DoesNotExist异常被吞

2. 为什么部分参数正常?

当你传入的参数对应的名称在关联表中只有1条记录时,get()能正常返回对象,过滤逻辑生效,返回结果符合预期;一旦对应名称有2条及以上记录,就会触发异常跳过过滤,返回全量数据。

修复方案
  1. 禁止使用裸except,明确捕获你需要处理的异常类型,同时可以加日志排查问题
  2. 建议直接用双下划线跨关联表查询,避免先查关联表再过滤的冗余逻辑,同时规避重复数据的问题
  3. 可选:给关联表的名称字段加唯一约束,从根源避免重复数据

修复后代码示例(views.py)

from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
import logging

logger = logging.getLogger(__name__)

class FilterVases(generics.ListAPIView):
    serializer_class = VaseSerializer 
    def get_queryset(self):
        queryset = Vase.objects.all()
        query_provenance = self.request.query_params.get('provenance_name')
        if query_provenance is not None:
            # 直接跨表查询,不需要先查Provenance表
            queryset = queryset.filter(provenance__provenanceName=query_provenance)
        
        inscription = self.request.query_params.get('inscription')
        if inscription is not None:
            queryset = queryset.filter(inscription=inscription)
        
        query_shape = self.request.query_params.get('shape_name')
        if query_shape is not None:
            queryset = queryset.filter(shape__shapeName=query_shape)
        
        query_collection = self.request.query_params.get('collection_name')
        if query_collection is not None:
            queryset = queryset.filter(collection__collectionName=query_collection)
        
        query_artist = self.request.query_params.get('artist_name')
        if query_artist is not None:
            queryset = queryset.filter(artist__artistName=query_artist)
        
        fabric = self.request.query_params.get('fabric')
        if fabric is not None:
            queryset = queryset.filter(fabric=fabric)
        
        vaseID = self.request.query_params.get('vaseID')
        if vaseID is not None:
            queryset = queryset.filter(vaseID=vaseID)
        
        return queryset

可选:给关联表加唯一约束(models.py)

class Shape(models.Model) :
    shapeID = models.CharField(max_length=10)
    shapeName = models.CharField(max_length=100, unique=True) # 加唯一约束

class Artist(models.Model) :
    artistID = models.CharField(max_length=10)
    artistName = models.CharField(max_length=100, unique=True) # 加唯一约束

class Provenance(models.Model) :
    ProvenanceID = models.CharField(max_length=10)
    provenanceName = models.CharField(max_length=100, unique=True) # 加唯一约束

class Collection(models.Model) :
    collectionID = models.CharField(max_length=10)
    collectionName = models.CharField(max_length=100, unique=True) # 加唯一约束

加完约束后执行makemigrations和migrate即可,后续入库重复名称会直接报错,避免脏数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 13:18:04