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> </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 }}&page={{ page.previous_page_number }}">{% endif %}« Previous{% if page.has_previous %}</a>{% endif %} | {% if page.has_next %}<a href="?q={{ query }}&page={{ page.next_page_number }}">{% endif %}Next »{% 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

