Django转PostgreSQL数据为JSON报错:'str' object has no attribute 'get'
解决Django中PostgreSQL数据转JSON的AttributeError问题
我来帮你一步步排查和解决这个问题,你遇到的AttributeError: 'str' object has no attribute 'get'和序列化错误都是因为数据处理流程的小问题导致的,咱们逐个解决:
核心问题分析
首先,JsonResponse的设计是接收Python原生数据结构(比如列表、字典),然后它会自动帮你完成JSON序列化。但你的marketer函数返回的是json.dumps()生成的字符串,这就导致JsonResponse把这个字符串当成了一个普通Python对象去处理,试图调用它的get方法(这是JsonResponse内部处理的逻辑),自然就报错了。
另外,你之前遇到的"not JSON serializable"错误,大概率是因为用普通cursor返回的是元组对象,而Django的序列化器无法直接处理元组,换成RealDictCursor是对的,但需要正确使用它。
修复步骤
1. 修正marketer.py的代码问题
先把函数里的语法错误和逻辑问题改掉:
- 去掉多余的
self参数(这不是类方法,不需要这个参数) - 修复
psycopg2.connect的参数格式错误(你把逗号写到引号外面了) - 不要用
json.dumps()返回字符串,直接返回cursor.fetchall()得到的字典列表 - 用上下文管理器(
with语句)确保数据库连接和cursor正确关闭,避免资源泄漏
修改后的marketer.py:
import psycopg2 from psycopg2.extras import RealDictCursor def get_marketers(): # 重命名函数更直观,去掉self参数 # 使用with上下文管理器自动管理连接和cursor with psycopg2.connect( user="db-user", password="*****", host="18.23.42.2", port="5432", database="db-name" ) as connection: with connection.cursor(cursor_factory=RealDictCursor) as cursor: postgreSQL_select_Query = "select id from auth_permission" cursor.execute(postgreSQL_select_Query) # 返回字典列表,而不是JSON字符串 return cursor.fetchall()
2. 修正views.py的调用逻辑
现在get_marketers()返回的是Python字典列表,直接传给JsonResponse即可,注意如果返回的是列表,需要加上safe=False参数(因为JsonResponse默认只接受字典类型,列表需要显式允许):
修改后的views.py:
from django.http import JsonResponse from .marketer import get_marketers # 导入修改后的函数 def marketer_list(request): # 获取字典列表 marketers_data = get_marketers() # 传入列表时需要设置safe=False return JsonResponse(marketers_data, safe=False)
为什么这样能解决问题?
RealDictCursor会把查询结果转换成Python字典,每个字典对应一行数据,键就是数据库的列名(这里是id)JsonResponse会自动把这个字典列表序列化成JSON格式的响应,不需要你手动调用json.dumps()- 上下文管理器确保数据库连接在使用后自动关闭,避免连接泄漏的问题
额外注意事项
- 确保你的数据库连接参数(用户名、密码、主机、端口、数据库名)都是正确的,否则会出现连接失败的错误
- 如果查询结果里有Django无法序列化的类型(比如日期时间),可以在返回前手动转换,比如把
datetime对象转成字符串:from datetime import datetime def convert_datetime(obj): if isinstance(obj, datetime): return obj.strftime('%Y-%m-%d %H:%M:%S') return obj # 在fetchall后处理每个字典 return [ {k: convert_datetime(v) for k, v in item.items()} for item in cursor.fetchall() ]
内容的提问来源于stack exchange,提问作者Hrithik Baishakhiya
相关产品推荐
相关产品推荐

