Django自定义非绑定模型Raw SQL填充时'status'参数错误排查
问题原因与解决方案
核心错误点
你遇到的TypeError: 'status' is an invalid keyword argument for this function,根源是模型字段定义的低级失误:
在consignment_status模型中,status字段的定义少了关键的括号:
status = models.TextField # 错误:仅引用了类,未实例化字段
models.TextField是一个类,必须通过加括号()来创建字段实例,否则Django的模型系统不会把它识别为合法的模型字段,自然无法通过关键字参数status来实例化模型对象。
修正后的代码
第一步:修复models.py中的字段定义
把status字段改为正确的实例化形式:
from django.db import models class list_consignment(models.Manager): def with_counts(self): import pyodbc cnxn = pyodbc.connect('Driver={SQL Server};Server=127.0.0.1;Database=TEST;uid=USERID;pwd=PASSWORD;') cursor = cnxn.cursor() with cnxn.cursor() as cursor: cursor.execute("""select t.ConsignmentNo, case when t2.TaskId = '50' then t2.TaskName when t2.TaskId IS NULL then 'NEW' else 'PENDING' end as 'status', case when t2.TaskId IS NOT NULL then t2.ActEnd else t.CreateDate end as created_time from ( select ConsignmentNo,JobEntry.CreateDate,JobEntry.JobStatus, max(ActEnd) as lastes_time from JobEntry left join jobTracking on JobEntry.JobNo = jobTracking.JobNo and JobEntry.companyid=jobTracking.companyid where JobEntry.companyid = 40 and JobEntry.CustomerCode = 'A000177' and ConsignmentNo like '%' and CAST(JobEntry.CreateDate as date) >= CAST(getdate()-1 as date) and JobEntry.iscancel = 0 group by ConsignmentNo, JobEntry.CreateDate,JobEntry.JobStatus ) t left Join ( select ConsignmentNo,JobEntry.CreateDate as jcreate_date, jobTracking.* from JobEntry left join jobTracking on JobEntry.JobNo = jobTracking.JobNo and JobEntry.companyid=jobTracking.companyid where JobEntry.companyid = 40 and JobEntry.BranchId = 40 and CAST(JobEntry.CreateDate as date) >= CAST(getdate()-1 as date) and JobEntry.CustomerCode = 'A000177' and ConsignmentNo like '%' )t2 on t.ConsignmentNo = t2.ConsignmentNo and t.lastes_time = t2.ActEnd and t.CreateDate = t2.jcreate_date order by status, ConsignmentNo""") result_list = [] for row in cursor.fetchall(): p = self.model(consignmentNo=row[0], status=row[1], created_time=row[2]) result_list.append(p) return result_list class consignment_status(models.Model): consignmentNo = models.CharField(max_length=100) status = models.TextField() # 此处添加括号,正确实例化字段 created_time = models.DateField() objects = list_consignment() class Meta: managed = False
第二步:修复views.py中的方法定义(额外优化)
你的dashboard类的get方法参数写错了,且返回数据的方式不符合API规范,建议调整:
from django.http import JsonResponse from rest_framework.views import APIView from rest_framework.permissions import AllowAny from .models import consignment_status class dashboard(APIView): permission_classes=(AllowAny,) # 修正参数:第一个参数应为self,而非APIView def get(self, request): data = {"data" : consignment_status.objects.with_counts()} # 使用JsonResponse返回标准JSON格式,safe=False适配列表类型数据 return JsonResponse(data, safe=False)
额外注意事项
- 若你的Raw SQL返回的
created_time包含具体时间,建议把模型中的created_time改为models.DateTimeField(),避免日期类型不匹配的错误。 - 生产环境中不要硬编码数据库账号密码,建议通过Django
settings.py或环境变量存储敏感信息。 - 管理器中的数据库连接记得关闭,可将连接也用
with语句包裹,避免资源泄漏:with pyodbc.connect('...') as cnxn: with cnxn.cursor() as cursor: # 执行SQL逻辑
内容的提问来源于stack exchange,提问作者JT_T
相关产品推荐
相关产品推荐

