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

Django集成Haystack-Whoosh无搜索结果且报错求助

Django Haystack-Whoosh 搜索无结果且抛出异常问题排查

你在Django应用里尝试用Haystack+Whoosh搭建搜索功能,严格遵循官方文档操作,但不仅搜不到预期结果,还碰到了底层的TypeError和AttributeError异常。先梳理你的代码和错误信息,再一步步排查问题:

你的代码文件

models.py

from django.db import models
from datetime import datetime
class Newcar(models.Model):
    car_name = models.CharField(max_length=50)
    carmodel = models.CharField(max_length=50)
    car_logo = models.CharField(max_length=1000)
    pub_date = models.DateTimeField(default=datetime.now())
    def __str__(self):
        return self.car_name + '-' + self.carmodel

search_indexes.py

import datetime
from haystack import indexes
from car.models import Newcar
class NewcarIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    car_name = indexes.CharField(model_attr='car_name')
    carmodel = indexes.CharField(model_attr='carmodel')
    pub_date = indexes.DateTimeField(model_attr='pub_date')
    def get_model(self):
        return Newcar
    def index_queryset(self, using=None):
        return self.get_model().objects.all()

newcar_text.txt(索引模板)

{{ object.car_name }} {{ object.carmodel }}

search.html

{% block content %}
<h2>Search</h2>
<form method="get" action=".">
<table>
{{ form.as_table }}
<tr>
<td>&nbsp;</td>
<td>
<input type="submit" value="Search">
</td>
</tr>
</table>
{% if query %}
<h3>Results</h3>
{% for result in page.object_list %}
<p>
<a href="{{ result.object.get_absolute_url }}">{{ result.object.car_name }}</a>
</p>
{% empty %}
<p>No results found.</p>
{% endfor %}
{% if page.has_previous or page.has_next %}
<div>
{% if page.has_previous %}<a href="?q={{ query }}&amp;page={{ page.previous_page_number }}">{% endif %}&laquo; Previous{% if page.has_previous %}</a>{% endif %} |
{% if page.has_next %}<a href="?q={{ query }}&amp;page={{ page.next_page_number }}">{% endif %}Next &raquo;{% if page.has_next %}</a>{% endif %}
</div>
{% endif %}
{% else %}
{% endif %}
</form>
{% endblock %}

你遇到的错误信息

File "C:\Users\hp\ENV\lib\site-packages\django\core\servers\basehttp.py", line 88, in handle_error
super(ServerHandler, self).handle_error()
File "c:\users\hp\appdata\local\programs\python\python36\Lib\wsgiref\handlers.py", line 368, in handle_error
self.finish_response()
File "c:\users\hp\appdata\local\programs\python\python36\Lib\wsgiref\handlers.py", line 180, in finish_response
self.write(data)
File "c:\users\hp\appdata\local\programs\python\python36\Lib\wsgiref\handlers.py", line 274, in write
self.send_headers()
File "c:\users\hp\appdata\local\programs\python\python36\Lib\wsgiref\handlers.py", line 331, in send_headers
if not self.origin_server or self.client_is_modern():
File "c:\users\hp\appdata\local\programs\python\python36\Lib\wsgiref\handlers.py", line 344, in client_is_modern
return self.environ['SERVER_PROTOCOL'].upper() != 'HTTP/0.9'
TypeError: 'NoneType' object is not subscriptable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "c:\users\hp\appdata\local\programs\python\python36 \Lib\socketserver.py", line 639, in process_request_thread
self.finish_request(request, client_address)
File "c:\users\hp\appdata\local\programs\python\python36\Lib\socketserver.py", line 361, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "c:\users\hp\appdata\local\programs\python\python36\Lib\socketserver.py", line 696, in __init__
self.handle()
File "C:\Users\hp\ENV\lib\site-packages\django\core\servers\basehttp.py", line 155, in handle
handler.run(self.server.get_app())
File "c:\users\hp\appdata\local\programs\python\python36\Lib\wsgiref\handlers.py", line 144, in run
self.close()
File "c:\users\hp\appdata\local\programs\python\python36\Lib\wsgiref\simple_server.py", line 35, in close
self.status.split(' ',1)[0], self.bytes_sent
AttributeError: 'NoneType' object has no attribute 'split'

问题排查与解决方案

先说明:你看到的服务器异常是二次错误,是Django开发服务器在处理初始错误时的崩溃,真正的问题需要从搜索功能本身的常见坑入手:

1. 必须生成搜索索引

这是Haystack最容易遗漏的步骤——你有没有执行过索引生成命令?

python manage.py rebuild_index

这个命令会把Newcar表中的所有数据写入Whoosh的索引文件。如果后续新增数据,可以用python manage.py update_index更新索引。

2. 修正pub_date的默认值

你的models.py里pub_date的默认值写法有问题:datetime.now()会导致所有新创建的对象都使用服务器启动时的时间,而不是对象创建时的时间。正确写法是:

# 推荐用Django的timezone模块
from django.utils import timezone
pub_date = models.DateTimeField(default=timezone.now)
# 或者保留datetime但不传括号
pub_date = models.DateTimeField(default=datetime.now)

虽然这不一定直接导致搜索无结果,但会影响后续基于时间的筛选逻辑,建议先修正。

3. 检查Haystack的URL配置

确保你在项目根urls.py中配置了Haystack的搜索路由:

from django.urls import path, include

urlpatterns = [
    # 其他路由...
    path('search/', include('haystack.urls')),
]

如果路由没配置,搜索表单提交后会找不到对应的处理视图,也会引发奇怪的错误。

4. 排查服务器二次异常

那个TypeError是wsgiref开发服务器的崩溃问题,可以尝试:

  • 重启Django开发服务器,缓存问题经常导致这类奇怪异常
  • 用gunicorn等生产级服务器测试,判断是开发服务器的问题还是代码本身的问题
  • 查看Django的日志文件,找更早的错误信息——真正的搜索失败原因可能被这个二次异常掩盖了

5. 验证Whoosh配置

确认settings.py中Haystack和Whoosh的配置正确:

INSTALLED_APPS = [
    # 其他APP...
    'haystack',
    'car',
]

HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
        'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
    },
}
# 可选:开启实时索引更新(新增/修改数据时自动更新索引)
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

同时确保whoosh_index目录存在且有读写权限。

6. 用Shell测试搜索API

在Django Shell中直接测试搜索功能,排除模板和视图的问题:

python manage.py shell
from haystack.query import SearchQuerySet
# 替换成你数据库中存在的关键词
results = SearchQuerySet().filter(content='测试车型')
print(results.count())
print([r.object.car_name for r in results])

如果这里能返回结果,说明问题出在search.html模板或视图配置上;如果这里也无结果,那就是索引生成的问题,重新执行rebuild_index并观察输出是否有错误。

按照这些步骤排查,应该能找到问题的根源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:09:20