Django代码runserver运行正常,Apache2下报Unsupported lookup 'exact'错误
问题根因
该报错和权限、Apache 基础配置无关,核心是 Apache 多进程模式下的 Django 模型元数据加载不一致,你遇到的报错提示看似矛盾(提示不支持exact查找却又建议用exact),本质是Django ORM没有识别到Channel模型存在last_played字段,误将你写的过滤条件判断为跨表关联查询,才抛出该错误。
出现差异的原因是python manage.py runserver为单进程运行模式,模型只会加载一次,状态始终一致;而Apache的mod_wsgi默认会启动多个独立的工作进程,出现该问题的触发场景通常是以下两种:
- 部署时没有完全清空Apache旧的工作进程,部分进程仍加载没有
last_played字段的旧版本模型代码 - SQLite数据库在多进程并发访问时出现元数据读取异常,导致ORM无法正常识别字段类型
解决步骤
- 首先完全重启Apache服务,清空所有残留进程,绝大多数该类问题都可以通过该操作解决:
sudo systemctl stop apache2 # 确认所有apache进程已退出 ps aux | grep -E 'apache2|www-data' | grep -v grep # 无输出后再启动服务 sudo systemctl start apache2 - 检查
Channel模型的字段定义,确保last_played是显式声明的BooleanField,不存在运行时动态修改、删除字段的逻辑:# 正确示例 class Channel(models.Model): # 其他字段省略 last_played = models.BooleanField(default=False, db_index=True) - 如果你需要继续使用SQLite数据库,可将Apache的mod_wsgi配置调整为单进程多线程模式(仅适合小流量个人场景),避免多进程访问SQLite的锁冲突,在你的站点虚拟主机配置中添加以下参数即可:
WSGIDaemonProcess jukeoroni processes=1 threads=15 - 若上述操作都无效,可在报错的
last_played属性代码前加日志打印,确认异常进程下的模型字段列表,排查是否有其他代码动态修改了模型元数据:@property def last_played(self): # 加这行打印字段列表到日志 LOG.info(f"Channel fields: {[f.name for f in Channel._meta.get_fields()]}") try: return Channel.objects.get(last_played=True) except Channel.DoesNotExist: LOG.info('no last_played channel, returning None.') return None
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

