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

如何在Django Tastypie中使用原生查询并关联表?遇报错求助

Django Tastypie 问题解决:RawQuerySet无filter属性与AppRegistryNotReady异常

问题1:RawQuerySet对象无filter属性

原因

EnergyPlantWise.objects.raw()返回的是RawQuerySet类型,它不支持Django标准QuerySet的filter、exclude等方法,而Tastypie的ModelResource内部会对queryset调用这些方法,导致触发异常。

解决方法

用Django ORM替代原生SQL,通过filter、annotate、values实现相同的分组聚合逻辑:

  • 用filter筛选指定年月的数据
  • 用values指定按fuel__name分组
  • 用annotate计算kwh的总和

问题2:AppRegistryNotReady异常

原因

在Meta类中直接定义queryset并执行数据库查询,这部分代码会在模块导入阶段运行,此时Django还未完成所有模型的加载,因此抛出异常。

解决方法

将动态查询逻辑(时间计算、条件过滤)移到资源类的get_queryset方法中,该方法会在Django完全初始化后才被调用。

修改后的完整代码

import datetime

from tastypie.resources import ModelResource
from generation.models import EnergyPlantWise, Fuel
from tastypie.authentication import BasicAuthentication
from django.db.models import Sum


class EnergyPlantWiseResource(ModelResource):
    class Meta:
        resource_name = 'epw'
        allowed_methods = ['get']
        excludes = ['id']
        authentication = BasicAuthentication()

    def get_queryset(self, request):
        present_time = datetime.datetime.today()
        previous_month = present_time.month - 1
        present_year = present_time.year
        
        # 用ORM实现原原生SQL的逻辑
        queryset = EnergyPlantWise.objects.filter(
            date__month=previous_month,
            date__year=present_year
        ).values('fuel__name').annotate(
            total_kwh=Sum('kwh')
        )
        return queryset

补充说明

  1. 避免使用from xxx.models import *,明确导入需要的模型,提升代码可读性并避免命名冲突。
  2. 如果确实需要使用原生SQL,可以重写obj_get_list方法处理RawQuerySet,但这种方式需要手动处理分页、过滤等逻辑,不如ORM便捷。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 06:22:15