Python遍历数据循环无法退出 报'str'对象无get属性错误
问题根因
报错'str' object has no attribute 'get'的核心原因是你遍历的request.data实际类型不符合预期,分两种常见场景:
- 前端请求未携带
Content-Type: application/json请求头,DRF无法将请求体解析为JSON数组,会把原始JSON字符串赋值给request.data。此时遍历字符串得到的每个元素都是单个字符(str类型),调用.get()方法直接触发报错。 - 前端传的请求体是JSON对象而非数组,此时遍历
request.data(字典类型)得到的是对象的键名(str类型),同样会触发.get()调用报错。
你提到所有数据都能写入数据库,说明部分请求中request.data是正确的列表格式,但代码没有做类型校验,一旦遇到格式不符合的请求就会抛错。除此之外你的代码还有3个明确逻辑问题:
result_st变量在每次循环中都会被覆写,最终只会保留最后一条存储过程的执行结果,之前所有行的返回值都会丢失- 数据库游标未做资源释放处理,异常场景下会残留数据库连接,拖垮服务性能
- 直接在循环外取
row[0]返回,如果传入空数组,循环未执行时row变量未定义,会触发新的变量不存在错误
修复方案
直接替换原有视图代码即可,修复点覆盖类型校验、异常兼容、资源释放、结果收集全流程:
from rest_framework.response import Response from rest_framework.decorators import api_view from django.db import connection import json @api_view(['POST']) def SaveUserResponse(request): if request.method != 'POST': return Response(0, status=405) req_data = request.data # 兼容request.data被解析为原始字符串的场景 if isinstance(req_data, str): try: req_data = json.loads(req_data) except json.JSONDecodeError: return Response({"code": 400, "msg": "请求格式错误,请传合法JSON"}, status=400) # 强制校验请求体必须为数组格式 if not isinstance(req_data, list): return Response({"code": 400, "msg": "请求体必须为JSON数组格式"}, status=400) exec_results = [] # 用上下文管理器自动管理游标连接,用完自动释放 with connection.cursor() as cursor: for row_data in req_data: # 跳过数组里非字典格式的脏数据 if not isinstance(row_data, dict): continue # 提取参数,不存在的字段默认给None避免KeyError auditorid = row_data.get('AuditorId') ticketid = row_data.get('TicketId') qid = row_data.get('QId') answer = row_data.get('Answer') sid = 0 # 执行存储过程 cursor.execute( 'EXEC [dbo].[sp_SaveAuditResponse] @auditorid=%s,@ticketid=%s,@qid=%s,@answer=%s,@sid=%s', (auditorid, ticketid, qid, answer, sid) ) # 收集当前行的执行结果 sp_result = cursor.fetchall() for res_row in sp_result: exec_results.append(res_row[0]) # 所有行处理完成后统一返回结果,无结果时默认返回0 return Response(exec_results if exec_results else 0)
调试&上线注意事项
- 前端调用接口时必须携带请求头
Content-Type: application/json,从根源上避免解析格式错误 - 本地调试时可以在循环开头加
print(type(row_data), row_data),如果打印出<class 'str'>就说明当前遍历到的元素是字符串,直接核对请求体格式即可定位问题 - 修复后的代码会收集每一条数据的存储过程返回值,不会出现之前只返回最后一条结果的问题
内容的提问来源于stack exchange,提问作者kelvin003
相关产品推荐
相关产品推荐

