django cms 搜索多个站点?

Posted

技术标签:

【中文标题】django cms 搜索多个站点?【英文标题】:django cms search with multiple sites? 【发布时间】:2011-09-04 19:55:18 【问题描述】:

我已经在 django cms 的单个实例中设置了多个站点,并使用 haystack 进行搜索(使用 Solr)。但是,我得到的 search_indexes.py 似乎没有任何效果。就像它只是被忽略并使用默认值一样。为什么我的 search_indexes.py 没有生效?

我有以下内容:

settings.py:

HAYSTACK_SITECONF = 'mysite.search_sites'

search_sites.py:

from cms.models import monkeypatch_reverse
import haystack

monkeypatch_reverse()
haystack.autodiscover()

mysite/app/search_indexes.py:

from django.conf import settings
from django.utils.translation import string_concat, ugettext_lazy
from django.utils.html import strip_tags

from haystack import indexes, site

from cms.models.managers import PageManager
from cms.models.pagemodel import Page
from cms.models.pluginmodel import CMSPlugin

def page_index_factory(lang, lang_name):
    if isinstance(lang_name, basestring):
        lang_name = ugettext_lazy(lang_name)

    def get_absolute_url(self):
        if 'cms.middleware.multilingual.MultilingualURLMiddleware' in settings.MIDDLEWARE_CLASSES:
            return '/%s%s' % (lang, Page.get_absolute_url(self))
        else:
            return Page.get_absolute_url(self)

    class Meta:
        proxy = True
        app_label = 'cms'
        if len(settings.LANGUAGES) > 1:
            verbose_name = string_concat(Page._meta.verbose_name, ' (', lang_name, ')')
            verbose_name_plural = string_concat(Page._meta.verbose_name_plural, ' (', lang_name, ')')
        else:
            verbose_name = Page._meta.verbose_name
            verbose_name_plural = Page._meta.verbose_name_plural

    attrs = '__module__': Page.__module__,
             'Meta': Meta,
             'objects': PageManager(),
             'get_absolute_url': get_absolute_url

    _PageProxy = type("Page_%s" % lang.title() , (Page,), attrs)

    _PageProxy._meta.parent_attr = 'parent'
    _PageProxy._meta.left_attr = 'lft'
    _PageProxy._meta.right_attr = 'rght'
    _PageProxy._meta.tree_id_attr = 'tree_id'

    class _PageIndex(indexes.SearchIndex):
        site_id = indexes.IntegerField(model_attr="site__id")
        language = lang
        text = indexes.CharField(document=True, use_template=False)
        pub_date = indexes.DateTimeField(model_attr='publication_date')
        login_required = indexes.BooleanField(model_attr='login_required')
        url = indexes.CharField(stored=True, indexed=False, model_attr='get_absolute_url')
        title = indexes.CharField(stored=True, indexed=False, model_attr='get_title')

        def prepare(self, obj):
            self.prepared_data = super(_PageIndex, self).prepare(obj)
            plugins = CMSPlugin.objects.filter(language=lang, placeholder__in=obj.placeholders.all())
            text = ''
            for plugin in plugins:
                instance, _ = plugin.get_plugin_instance()
                if hasattr(instance, 'search_fields'):
                    text += ''.join(strip_tags(getattr(instance, field, '')) for field in instance.search_fields)
                if getattr(instance, 'search_fulltext', False):
                    text += strip_tags(instance.render_plugin())
            self.prepared_data['text'] = text
            return self.prepared_data

        def index_queryset(self):
            qs = _PageProxy.objects.published().filter(title_set__language=lang).distinct()
            if 'publisher' in settings.INSTALLED_APPS:
                qs = qs.filter(publisher_is_draft=True)
            return qs

    return _PageProxy, _PageIndex

for lang_tuple in settings.LANGUAGES:
    lang, lang_name = lang_tuple
    site.register(*page_index_factory(lang, lang_name))

【问题讨论】:

如果可能的话,您能否将您的解决方案添加为答案而不是编辑?这样人们就可以看到它已被回答,并且它不会出现在 Django 问题的“未回答”选项卡中。 :) 他可能很久以前就离开了。我正在将他的解决方案复制并粘贴到答案框中。我会标记它并解释我已经复制了解决方案,并且该问题应标记为已批准。 【参考方案1】:

好的,所以问题出在不应该使用自动发现的 search_sites.py 上。相反,它需要导入 search_indexes 文件,该文件将为所有插件注册索引:

from cms.models import monkeypatch_reverse
monkeypatch_reverse()
import mysite.app.search_indexes

然后以下脚本在所有站点上运行索引:

import os
import sys

root = os.path.join(os.path.dirname(__file__), '..')
sys.path.insert(0, root)

activate_this = os.path.join(root, 'venv/bin/activate_this.py')
execfile(activate_this, dict(__file__=activate_this))
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'

from django.contrib.sites.models import Site
from django.conf import settings

from haystack.management.commands.clear_index import Command as clearCommand
from haystack.management.commands.update_index import Command as updateCommand

clear = clearCommand()
clear.handle(interactive=False)

for site in Site.objects.all():
    settings.SITE_ID = site.id
    update = updateCommand()
    update.handle()

【讨论】:

以上是关于django cms 搜索多个站点?的主要内容,如果未能解决你的问题,请参考以下文章

Django-cms:“设置”对象没有属性“SITE_ID”

如何在同一个域下部署多个 django cms 项目。我使用的是 apache 2.2 和 mod_wsgi

Django CMS 搜索引擎,几个问题

Django 中的多个站点

如何在由“站点”框架提供支持的多个 Django 站点中获取唯一用户?

如何为站点框架 django 设置多个 settings.py?