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

Django多对多模型Admin页面报InvalidCursorName错误求助

解决Django + PostgreSQL Admin操作多对多字段时的InvalidCursorName异常

我之前碰到过完全类似的问题,结合你的环境配置(Python3.5、Django2.2.7、psycopg2 2.8.4、PostgreSQL9.5.19),这个异常基本是游标生命周期管理冲突或者版本兼容性bug导致的——SQLite不会出现是因为它的游标实现逻辑和PostgreSQL差异很大。下面是具体的排查和解决步骤:

一、优先排查版本兼容性

Django 2.2对psycopg2和PostgreSQL的版本有明确的兼容范围,你当前的版本组合可能存在游标相关的bug:

  • 尝试降级psycopg2到2.8.3:这个版本修复了老PostgreSQL版本下的游标兼容性问题
    pip install psycopg2==2.8.3
    
  • 或者升级psycopg2到2.9.x系列(注意Python3.5最高支持2.9.6版本):新版本对游标管理逻辑做了优化
    pip install psycopg2==2.9.6
    

二、检查数据库连接配置

如果版本调整后问题依然存在,大概率是连接复用导致的游标失效:

  1. 禁用或调整连接复用时长:在settings.py的DATABASES配置中,把CONN_MAX_AGE设为0(禁用连接复用),或者调整为较小的值(比如60秒),避免复用的连接中游标被提前清理:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': '你的数据库名',
            'USER': '你的数据库用户',
            'PASSWORD': '你的数据库密码',
            'HOST': 'localhost',
            'PORT': '5432',
            'CONN_MAX_AGE': 0,  # 临时禁用连接复用
        }
    }
    
  2. 检查连接池配置:如果你用了pgBouncer这类连接池,必须确保它的pool_mode设置为session模式,transaction或statement模式会破坏Django需要的会话级游标生命周期:
    # pgBouncer配置示例
    [pgbouncer]
    pool_mode = session
    

三、排查Admin自定义代码

如果你给Model2写了自定义的Admin类,检查是否有以下情况:

  • 自定义了表单的clean或save方法,意外关闭了数据库游标
  • 重载了Admin的save_model方法,手动操作数据库时没有正确管理游标

可以先暂时用默认Admin类测试:

from django.contrib import admin
from .models import Model2

admin.site.register(Model2)

四、临时Workaround:自定义数据库后端

如果以上方法都无效,可以自定义PostgreSQL后端,强制游标正确创建:

  1. 在项目中创建db_backends/postgresql/base.py:
    from django.db.backends.postgresql.base import DatabaseWrapper
    
    class CustomPostgreSQLWrapper(DatabaseWrapper):
        def _cursor(self, name=None):
            # 强制创建新游标,避免复用失效的游标
            cursor = super()._cursor(name)
            if name and not cursor:
                cursor = self.connection.cursor(name=name)
            return cursor
    
  2. 在settings.py中修改数据库引擎:
    DATABASES = {
        'default': {
            'ENGINE': '你的项目名.db_backends.postgresql',
            # 其他配置不变
        }
    }
    

完成以上操作后,重启Django服务,再尝试在Admin中创建/修改Model2对象,应该就能解决InvalidCursorName异常了。

内容的提问来源于stack exchange,提问作者Kappa Sama

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:48:10