Skip to content

Commit

Permalink
Skip haystack index creation if aldryn-search is not installed (nephi…
Browse files Browse the repository at this point in the history
…la#585)

* Skip haystack index creation if aldryn-search is not installed but haystack is
  • Loading branch information
yakky authored Jun 21, 2020
1 parent 858b148 commit 3d6e2e3
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 83 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ jobs:
exclude:
- python-version: 3.5
django: 30
include:
- python-version: 3.8
django: 22
cms: no-search-37
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
Expand Down
1 change: 1 addition & 0 deletions changes/584.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Skip haystack index creation if aldryn-search is not installed but haystack is
9 changes: 8 additions & 1 deletion cms_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ def gettext(s):
"taggit",
"taggit_autosuggest",
"aldryn_apphooks_config",
"aldryn_search",
"djangocms_video",
"sortedm2m",
"tests.media_app",
Expand Down Expand Up @@ -79,6 +78,14 @@ def gettext(s):
}
except ImportError:
pass


try:
import aldryn_search # pragma: no cover # NOQA

HELPER_SETTINGS["INSTALLED_APPS"].append("aldryn_search")
except ImportError:
pass
os.environ["AUTH_USER_MODEL"] = "tests.test_utils.CustomUser"

if "server" in sys.argv[:3]:
Expand Down
160 changes: 82 additions & 78 deletions djangocms_blog/search_indexes.py
Original file line number Diff line number Diff line change
@@ -1,78 +1,82 @@
from aldryn_search.helpers import get_plugin_index_data
from aldryn_search.utils import get_index_base, strip_tags
from django.utils.encoding import force_str
from haystack import indexes
from parler.utils.context import switch_language

from .models import Post
from .settings import get_setting


class PostIndex(get_index_base()):
haystack_use_for_indexing = get_setting("ENABLE_SEARCH")

index_title = True

author = indexes.CharField(indexed=True, model_attr="get_author")
keywords = indexes.CharField(null=True)
tags = indexes.CharField(null=True, model_attr="get_tags")
post_text = indexes.CharField(null=True)

def get_title(self, post):
return post.get_title()

def get_description(self, post):
return post.get_description()

def prepare_pub_date(self, post):
return post.date_published

def index_queryset(self, using=None):
self._get_backend(using)
language = self.get_current_language(using)
filter_kwargs = self.get_index_kwargs(language)
qs = self.get_index_queryset(language)
if filter_kwargs:
return qs.translated(language, **filter_kwargs)
return qs

def get_index_queryset(self, language):
return self.get_model().objects.published().active_translations(language_code=language)

def get_model(self):
return Post

def get_search_data(self, post, language, request):
with switch_language(post, language):
description = post.get_description()
abstract = strip_tags(post.safe_translation_getter("abstract", default=""))
keywords = post.get_keywords()

text_bits = []
if abstract:
text_bits.append(abstract)
if description:
text_bits.append(description)
if keywords:
text_bits.append(" ".join(keywords))
self.prepared_data["keywords"] = ",".join(keywords)
for category in post.categories.all():
text_bits.append(force_str(category.safe_translation_getter("name")))
for tag in post.tags.all():
text_bits.append(force_str(tag.name))

if get_setting("USE_PLACEHOLDER"):
plugins = post.content.cmsplugin_set.filter(language=language)
content_bits = []
for base_plugin in plugins:
content = get_plugin_index_data(base_plugin, request)
content_bits.append(" ".join(content))
post_text = " ".join(content_bits)
else:
post_text = post.safe_translation_getter("post_text")
if post_text:
post_text = strip_tags(post_text)
self.prepared_data["post_text"] = post_text
text_bits.append(post_text)

return " ".join(text_bits)
try:
from aldryn_search.helpers import get_plugin_index_data
from aldryn_search.utils import get_index_base, strip_tags
from django.utils.encoding import force_str
from haystack import indexes
from parler.utils.context import switch_language

from .models import Post
from .settings import get_setting

class PostIndex(get_index_base()):
haystack_use_for_indexing = get_setting("ENABLE_SEARCH")

index_title = True

author = indexes.CharField(indexed=True, model_attr="get_author")
keywords = indexes.CharField(null=True)
tags = indexes.CharField(null=True, model_attr="get_tags")
post_text = indexes.CharField(null=True)

def get_title(self, post):
return post.get_title()

def get_description(self, post):
return post.get_description()

def prepare_pub_date(self, post):
return post.date_published

def index_queryset(self, using=None):
self._get_backend(using)
language = self.get_current_language(using)
filter_kwargs = self.get_index_kwargs(language)
qs = self.get_index_queryset(language)
if filter_kwargs:
return qs.translated(language, **filter_kwargs)
return qs

def get_index_queryset(self, language):
return self.get_model().objects.published().active_translations(language_code=language)

def get_model(self):
return Post

def get_search_data(self, post, language, request):
with switch_language(post, language):
description = post.get_description()
abstract = strip_tags(post.safe_translation_getter("abstract", default=""))
keywords = post.get_keywords()

text_bits = []
if abstract:
text_bits.append(abstract)
if description:
text_bits.append(description)
if keywords:
text_bits.append(" ".join(keywords))
self.prepared_data["keywords"] = ",".join(keywords)
for category in post.categories.all():
text_bits.append(force_str(category.safe_translation_getter("name")))
for tag in post.tags.all():
text_bits.append(force_str(tag.name))

if get_setting("USE_PLACEHOLDER"):
plugins = post.content.cmsplugin_set.filter(language=language)
content_bits = []
for base_plugin in plugins:
content = get_plugin_index_data(base_plugin, request)
content_bits.append(" ".join(content))
post_text = " ".join(content_bits)
else:
post_text = post.safe_translation_getter("post_text")
if post_text:
post_text = strip_tags(post_text)
self.prepared_data["post_text"] = post_text
text_bits.append(post_text)

return " ".join(text_bits)


except ImportError:
pass
2 changes: 2 additions & 0 deletions docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ If you want to enable haystack support, in addition to the above:
* add ``aldryn_search`` to ``INSTALLED_APPS``
* configure haystack according to `aldryn-search docs <https://github.com/aldryn/aldryn-search#usage>`_
and `haystack docs <http://django-haystack.readthedocs.io/en/stable/>`_.
* if not using ``aldryn_search``, you can define your own ``search_indexes.py`` by skipping ``aldryn_search`` installation and writing
your index for blog posts by following haystack documentation.

To enable taggit filtering support in the admin install djangocms-blog with:

Expand Down
1 change: 0 additions & 1 deletion requirements-test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ invoke
tox>=2.0
wheel
pysolr
aldryn-search
django-taggit-helpers
django-app-helper>=2.0.0a2
sphinx-autobuild
Expand Down
33 changes: 32 additions & 1 deletion tests/test_indexing.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
from unittest import skipIf

from cms.api import add_plugin
from django.test import override_settings
from haystack.constants import DEFAULT_ALIAS
from haystack.query import SearchQuerySet

from djangocms_blog.models import Post

from .base import BaseTest

try:
import aldryn_search
except ImportError:
aldryn_search = None


class BlogIndexingTests(BaseTest):
sample_text = "First post first line This is the description keyword1 " "keyword2 category 1 a tag test body"
sample_text = "First post first line This is the description keyword1 keyword2 category 1 a tag test body"

def setUp(self):
self.get_pages()

@skipIf(aldryn_search is None, "aldryn-search not installed")
def test_blog_post_is_indexed_using_prepare(self):
"""This tests the indexing path way used by update_index mgmt command"""
post = self._get_post(self._post_data[0]["en"])
Expand All @@ -31,6 +40,28 @@ def test_blog_post_is_indexed_using_prepare(self):
self.assertEqual(post.get_absolute_url(), indexed["url"])
self.assertEqual(post.date_published, indexed["pub_date"])

@skipIf(aldryn_search is None, "aldryn-search not installed")
@override_settings(BLOG_USE_PLACEHOLDER=False)
def test_blog_post_is_indexed_using_prepare_no_placeholder(self):
"""This tests the indexing path way used by update_index mgmt command when not using placeholder content"""
post = self._get_post(self._post_data[0]["en"])
post = self._get_post(self._post_data[0]["it"], post, "it")
post.tags.add("a tag")
add_plugin(post.content, "TextPlugin", language="en", body="test body")
post.post_text = "non placeholder content"

index = self.get_post_index()
index.index_queryset(DEFAULT_ALIAS) # initialises index._backend_alias
indexed = index.prepare(post)

self.assertEqual(post.get_title(), indexed["title"])
self.assertEqual(post.get_description(), indexed["description"])
self.assertEqual(post.get_tags(), indexed["tags"])
self.assertNotEqual(self.sample_text, indexed["text"])
self.assertTrue(post.post_text in indexed["text"])
self.assertEqual(post.get_absolute_url(), indexed["url"])
self.assertEqual(post.date_published, indexed["pub_date"])

def test_searchqueryset(self):
posts = self.get_posts()
all_results = SearchQuerySet().models(Post)
Expand Down
7 changes: 5 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ envlist =
pep8
pypi-description
towncrier
py{3.8,3.7,3.6}-django{30}-cms{37}
py{3.8,3.7,3.6,3.5}-django{22}-cms{37}
py{3.8,3.7,3.6}-django{30}-cms{37,no-search-37}
py{3.8,3.7,3.6,3.5}-django{22}-cms{37,no-search-37}

[testenv]
commands = {env:COMMAND:python} cms_helper.py djangocms_blog test {posargs}
Expand All @@ -18,13 +18,16 @@ deps =
django22: django-mptt>=0.8
django22: django-filer>=1.5,<1.6
django22: django-appdata>=0.2.2
django22: django-haystack
django30: Django>=3.0,<3.1
django30: django-mptt>=0.9
django30: django-filer>=1.6
django30: django-appdata>=0.3.0
django30: django-haystack==3.0b2
django30: https://github.com/yakky/djangocms-text-ckeditor/archive/master.zip
cms37: https://github.com/divio/django-cms/archive/release/3.7.x.zip
cms37: aldryn-search
cms-no-search-37: https://github.com/divio/django-cms/archive/release/3.7.x.zip
channels>2
https://github.com/nephila/django-knocker/archive/master.zip
channels-redis
Expand Down

0 comments on commit 3d6e2e3

Please sign in to comment.