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

django-oscar扩展CheckoutSerializer测试时未用PriceSerializer却报类不存在错误

问题根因

从堆栈跟踪可以明确看到错误触发链路:

  • 测试文件导入自定义CheckoutSerializer → 触发导入自定义checkout序列化器模块
  • 自定义checkout模块导入oscar-api原生checkout序列化器 → oscar-api的类加载机制会优先加载你项目中自定义的序列化器扩展
  • 加载自定义basket序列化器时触发自定义product序列化器导入 → 你的store/apps/api_extensions/serializers/product.py第29行在模块顶层直接调用get_api_class尝试加载serializers.checkout下的PriceSerializer
  • 此时自定义checkout模块还处于加载中,尚未完成PriceSerializer的注册/定义,类加载器在自定义、原生两个路径下都找不到对应类,触发报错。

运行时无问题是因为正常请求场景下的模块导入顺序和测试导入场景不同,加载到PriceSerializer时checkout模块已经完成加载,不会触发循环加载导致的类找不到问题。

解决方案

你可以选择以下任意一种方案修复:

  • 方案1:移除模块顶层的动态加载,改为动态导入
    不要在product.py的模块顶层调用get_api_class加载PriceSerializer,如果是在序列化器字段中使用,可以用DRF的字符串懒加载配置,例如:
    # 替换原来的模块顶层PriceSerializer导入
    price = serializers.SerializerMethodField()
    # 或者字段指定序列化器时用字符串路径
    price_info = serializers.Serializer(source='*', serializer_class='apps.api_extensions.serializers.checkout.PriceSerializer')
    
    如果是在方法中使用,将导入逻辑移动到方法内部:
    def get_price(self, instance):
        from oscarapi.utils.loading import get_api_class
        PriceSerializer = get_api_class("serializers.checkout", "PriceSerializer")
        return PriceSerializer(instance.price, context=self.context).data
    
  • 方案2:直接导入原生类跳过动态加载
    如果你不需要自定义PriceSerializer,不要用get_api_class加载,直接从oscar-api原生路径导入即可,避免类加载器去自定义扩展路径查找:
    from oscarapi.serializers.checkout import PriceSerializer
    
  • 方案3:补全自定义类定义
    如果你确实需要自定义PriceSerializer,直接在你的store/apps/api_extensions/serializers/checkout.py模块中定义该类即可,类加载器会优先加载你自定义的实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 11:09:00