如何在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
补充说明
- 避免使用
from xxx.models import *,明确导入需要的模型,提升代码可读性并避免命名冲突。 - 如果确实需要使用原生SQL,可以重写
obj_get_list方法处理RawQuerySet,但这种方式需要手动处理分页、过滤等逻辑,不如ORM便捷。
内容的提问来源于stack exchange,提问作者Taufique Alam
相关产品推荐
相关产品推荐

