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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:33:01