利用 Django 建站攻略 (四)搜索

django-haystack 是 Django 搜索组建的封装 官方文档

支持:

  • solr

  • Elasticsearch

  • Xapian

  • Whoosh

这里主要介绍 Whoosh。当然,solr, elasticsearch 当然有更好的性能。因为穷,只有一台服务器。就凑合下用用吧。

安装:

pip install django-haystack
pip install whoosh
pip install jieba

配置: 在 settings.py 添加以下配置

INSTALLED_APPS += [

    'haystack', #添加 haystack app
]

import os
HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
        'PATH': os.path.join(os.path.dirname(__file__), 'whoosh_index'),
    },
}

处理数据:

在需要建立索引的 app 下创建一个 search_indexes.py 文件, 添加要建立搜索的 model 和字段。

from haystack import indexes
from app.models import Project

class ProjectIndex(indexes.SearchIndex, indexes.Indexable):
    text        = indexes.CharField(document=True, use_template=True)
    author      = indexes.CharField(model_attr='author',)
    name        = indexes.CharField(model_attr='name',)
    category    = indexes.CharField(model_attr='category')
    desc        = indexes.CharField(model_attr='desc')
    url         = indexes.CharField(model_attr='get_absolute_url')
    display     = indexes.BooleanField(model_attr='display')
    star        = indexes.IntegerField(model_attr='latest_star')
    watch       = indexes.IntegerField(model_attr='latest_watch')
    fork        = indexes.IntegerField(model_attr='latest_fork')

    name_auto   = indexes.EdgeNgramField(model_attr='name')

    def get_model(self):
        return Project

    def index_queryset(self, using=None):
        return self.get_model().objects.all()

然后在 templates 文件夹下创建 search/indexes/app/project_text.txt

{{ object.author }}
{{ object.name }}
{{ object.category }}
{{ object.desc }}

配置 urls.py

(r'^search/', include('haystack.urls')),

建索引

cd /path/to/myproject/
python manage.py rebuild_index

最后写一个 search.html**

{% extends 'base.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.title }}</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 %}
            {# Show some example queries to run, maybe query syntax, something else? #}
        {% endif %}
    </form>
{% endblock %}

大功告成!!


系列教程: