Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
36844e4
Update tutorial.rst
erez-o May 16, 2018
156580e
Update installing_search_engines.rst
erez-o May 16, 2018
dd2eaf6
Update flake8 ignores
acdha Jun 18, 2018
36390dc
Fix all “not FOO in BAR” tests
acdha Jun 18, 2018
9feb2b3
Stop declaring unused variables
acdha Jun 18, 2018
6afd232
Fix remaining long line warnings
acdha Jun 18, 2018
0dde1c4
Fix unnecessary `== True` test
acdha Jun 18, 2018
fcb8ced
Whitespace
acdha Jun 18, 2018
2dddd02
More-Like-This template tag: log exceptions’
acdha Jun 18, 2018
cfb0bfe
Remove unused logging code
acdha Jun 18, 2018
018bcfa
Update Solr server startup script for Java 10
acdha Jun 19, 2018
39c2adc
Stop re-exporting Django classes
acdha Jun 19, 2018
54f51fb
Mark intentional exports from indexes
acdha Jun 19, 2018
b607696
Fixes #1624: SearchQuerySet is instantiated at startup
Jul 4, 2018
7103ca2
Update backend support doc (closes #1626)
acdha Jul 9, 2018
2831d08
Merge pull request #1625 from batisteo/1624-searchqueryset-instanciated
acdha Jul 9, 2018
3e5b37d
Add Elasticsearch example for adjusting highlight tags.
higs4281 Jul 12, 2018
bbcd038
Merge pull request #1628 from higs4281/master
acdha Jul 13, 2018
6c4a854
Merge pull request #1608 from erez-o/master
acdha Jul 16, 2018
f6f3f4e
Remove compatibility shims for Django < 1.4
timgraham Sep 17, 2018
b4ea18c
Merge pull request #1642 from timgraham/django13
acdha Sep 17, 2018
78b8b0c
Add Django 2.1 compatibility
timgraham Sep 17, 2018
ed734df
Excluded pypy/Django 2.0 from Travis
timgraham Sep 17, 2018
f35e908
Merge pull request #1641 from timgraham/django21
acdha Sep 17, 2018
7d65231
QueryParser of super(WhooshSearchBackend, self).__init__(incl…
Sep 27, 2018
1208085
fix whoosh test for the extended fuzzy search options
Sep 27, 2018
852dd3d
bugfix: whoosh min. prefix length less than query term length
Sep 27, 2018
e60031f
Merge pull request #1645 from trybik/whoosh_fuzzy_search
acdha Sep 27, 2018
637b1c8
Test enabling codecov
acdha Nov 2, 2018
4136ad7
Merge pull request #1649 from acdha/enable-codecov
acdha Nov 2, 2018
c86893c
Move import into function to avoid GDAL as a global dependency
Jan 7, 2019
d0e6cbb
Also move geo imports into test functions
Jan 7, 2019
57bb39c
Export NgramField from indexes once again
asedeno Jan 7, 2019
7044c91
Merge pull request #1657 from asedeno/master
acdha Jan 8, 2019
802b0f6
Merge pull request #1656 from mpauly/move-import
acdha Jan 8, 2019
c80aa7c
remove all instances of from django.utils import six
eritter688 Nov 2, 2020
ab7855a
remove all instances of from django.utils import six
eritter688 Nov 2, 2020
4de3099
change django.utils.encoding.python_2_unicode_compatible to six.pytho…
eritter688 Nov 2, 2020
6e7de2e
Merge branch 'model_filter_es5' into django3
eritter688 Nov 2, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 48 additions & 17 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,26 @@ before_install:
# See https://www.elastic.co/guide/en/elasticsearch/reference/current/deb.html#deb-repo
- wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
- >
if [[ $VERSION_ES == '>=2.0.0,<3.0.0' ]];
then
echo "deb http://packages.elastic.co/elasticsearch/2.x/debian stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-2.x.list
sudo apt-get update
sudo apt-get -qy --allow-downgrades install elasticsearch=2.4.6
elif [[ $VERSION_ES == '>=5.0.0,<6.0.0' ]];
then
echo "deb https://artifacts.elastic.co/packages/5.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-5.x.list
sudo apt-get update -qy
sudo apt-get -y --allow-downgrades install elasticsearch=5.6.10
else
echo "deb http://packages.elastic.co/elasticsearch/1.7/debian stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-1.7.list
sudo apt-get update -qy
sudo apt-get -qy --allow-downgrades install elasticsearch=1.7.6
fi
if [[ $VERSION_ES == '>=2.0.0,<3.0.0' ]];
then
echo "deb http://packages.elastic.co/elasticsearch/2.x/debian stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-2.x.list
sudo apt-get update
sudo apt-get -qy --allow-downgrades install elasticsearch=2.4.6
elif [[ $VERSION_ES == '>=5.0.0,<6.0.0' ]];
then
echo "deb https://artifacts.elastic.co/packages/5.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-5.x.list
sudo apt-get update -qy
sudo apt-get -y --allow-downgrades install elasticsearch=5.6.10
else
echo "deb http://packages.elastic.co/elasticsearch/1.7/debian stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-1.7.list
sudo apt-get update -qy
sudo apt-get -qy --allow-downgrades install elasticsearch=1.7.6
fi
- sudo service elasticsearch restart

install:
- pip install --upgrade setuptools
- pip install codecov coverage
- pip install requests "Django${DJANGO_VERSION}" "elasticsearch${VERSION_ES}"
- python setup.py clean build install

Expand All @@ -59,16 +60,22 @@ before_script:

script:
- python test_haystack/solr_tests/server/wait-for-solr
- python setup.py test
- coverage run setup.py test

after_success:
- codecov

env:
matrix:
- DJANGO_VERSION=">=1.11,<2.0" VERSION_ES=">=1.0.0,<2.0.0"
- DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=1.0.0,<2.0.0"
- DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=1.0.0,<2.0.0"
- DJANGO_VERSION=">=1.11,<2.0" VERSION_ES=">=2.0.0,<3.0.0"
- DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=2.0.0,<3.0.0"
- DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=2.0.0,<3.0.0"
- DJANGO_VERSION=">=1.11,<2.0" VERSION_ES=">=5.0.0,<6.0.0"
- DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=5.0.0,<6.0.0"
- DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=5.0.0,<6.0.0"
matrix:
allow_failures:
- python: 'pypy'
Expand All @@ -79,7 +86,31 @@ matrix:
env: DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=2.0.0,<3.0.0"
- python: 2.7
env: DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=1.0.0,<2.0.0"
- python: 2.7
env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=5.0.0,<6.0.0"
- python: 2.7
env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=2.0.0,<3.0.0"
- python: 2.7
env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=1.0.0,<2.0.0"
- python: 3.4
env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=5.0.0,<6.0.0"
- python: 3.4
env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=2.0.0,<3.0.0"
- python: 3.4
env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=1.0.0,<2.0.0"
- python: pypy
env: DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=5.0.0,<6.0.0"
- python: pypy
env: DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=2.0.0,<3.0.0"
- python: pypy
env: DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=1.0.0,<2.0.0"
- python: pypy
env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=5.0.0,<6.0.0"
- python: pypy
env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=2.0.0,<3.0.0"
- python: pypy
env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=1.0.0,<2.0.0"

notifications:
irc: "irc.freenode.org#haystack"
irc: 'irc.freenode.org#haystack'
email: false
2 changes: 1 addition & 1 deletion docs/backend_support.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ ElasticSearch
* Stored (non-indexed) fields
* Highlighting
* Spatial search
* Requires: `elasticsearch-py <https://pypi.python.org/pypi/elasticsearch>`_ 1.x or 2.x. ElasticSearch 5.X is currently unsupported: see `#1383 <https://github.com/django-haystack/django-haystack/issues/1383>`_.
* Requires: `elasticsearch-py <https://pypi.python.org/pypi/elasticsearch>`_ 1.x, 2.x, or 5.X.

Whoosh
------
Expand Down
4 changes: 2 additions & 2 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ Changelog

Add max-retries argument to rebuild_index managment command. This is useful for debug at development time

Add Django 2.1 compatibility. [Tim Graham]


v2.8.1 (2018-03-16)
-------------------
Expand Down Expand Up @@ -4112,5 +4114,3 @@ v1.1 (2010-11-23)
[Daniel Lindsley]
- Initial commit. Basic IndexSite implementation complete. Needs tests.
[Daniel Lindsley]


4 changes: 3 additions & 1 deletion docs/installing_search_engines.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ Solr 4.x+ with a little effort. Installation is relatively simple:
For Solr 6.X::

curl -LO https://archive.apache.org/dist/lucene/solr/x.Y.0/solr-X.Y.0.tgz
mkdir solr
tar -C solr -xf solr-X.Y.0.tgz --strip-components=1
cd solr
./bin/solr create -c tester -n basic_config
./bin/solr start # start solr
./bin/solr create -c tester -n basic_config # create core named 'tester'

By default this will create a core with a managed schema. This setup is dynamic
but not useful for haystack, and we'll need to configure solr to use a static
Expand Down
8 changes: 8 additions & 0 deletions docs/searchqueryset_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,14 @@ instead of normal keyword arguments::
result = sqs[0]
result.highlighted['other_field'][0] # u'Two computer scientists walk into a bar. The bartender says "<span class="highlighted">Foo</span>!".'

Elasticsearch accepts keyword arguments::

# Use the ``pre_tag`` and ``post_tag`` keywords and pass the desired tags as lists.
sqs = SearchQuerySet().filter(content='foo').highlight(
pre_tags=['<strong>'], post_tags=['</strong>'])
result_example = " ".join(sqs[0].highlighted)
# u'Two <strong>foo</strong> computer scientists walk into a bar. The bartender says "<strong>Foo</strong>!"'

``models``
~~~~~~~~~~

Expand Down
20 changes: 9 additions & 11 deletions docs/spatial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ Geospatial Assumptions
----------

Haystack prefers to work with ``Point`` objects, which are located in
``django.contrib.gis.geos.Point`` but conviently importable out of
``haystack.utils.geo.Point``.
``django.contrib.gis.geos.Point``.

``Point`` objects use **LONGITUDE, LATITUDE** for their construction, regardless
if you use the parameters to instantiate them or WKT_/``GEOSGeometry``.
Expand All @@ -76,7 +75,7 @@ if you use the parameters to instantiate them or WKT_/``GEOSGeometry``.
Examples::

# Using positional arguments.
from haystack.utils.geo import Point
from django.contrib.gis.geos import Point
pnt = Point(-95.23592948913574, 38.97127105172941)

# Using WKT.
Expand All @@ -92,8 +91,7 @@ with GeoDjango's use.
------------

Haystack also uses the ``D`` (or ``Distance``) objects from GeoDjango,
implemented in ``django.contrib.gis.measure.Distance`` but conveniently
importable out of ``haystack.utils.geo.D`` (or ``haystack.utils.geo.Distance``).
implemented in ``django.contrib.gis.measure.Distance``.

``Distance`` objects accept a very flexible set of measurements during
instantiaton and can convert amongst them freely. This is important, because
Expand All @@ -102,7 +100,7 @@ whatever units you want.

Examples::

from haystack.utils.geo import D
from django.contrib.gis.measure import D

# Start at 5 miles.
imperial_d = D(mi=5)
Expand Down Expand Up @@ -223,7 +221,7 @@ point. It is faster but slighty sloppier than its counterpart.
Examples::

from haystack.query import SearchQuerySet
from haystack.utils.geo import Point
from django.contrib.gis.geos import Point

downtown_bottom_left = Point(-95.23947, 38.9637903)
downtown_top_right = Point(-95.23362278938293, 38.973081081164715)
Expand Down Expand Up @@ -263,7 +261,7 @@ calculations on your part.
Examples::

from haystack.query import SearchQuerySet
from haystack.utils.geo import Point, D
from django.contrib.gis.geos import Point, D

ninth_and_mass = Point(-95.23592948913574, 38.96753407043678)
# Within a two miles.
Expand Down Expand Up @@ -306,7 +304,7 @@ include these calculated distances on results.
Examples::

from haystack.query import SearchQuerySet
from haystack.utils.geo import Point, D
from django.contrib.gis.geos import Point, D

ninth_and_mass = Point(-95.23592948913574, 38.96753407043678)

Expand All @@ -324,7 +322,7 @@ key, well-cached hotspots in town but want distances from the user's current
position::

from haystack.query import SearchQuerySet
from haystack.utils.geo import Point, D
from django.contrib.gis.geos import Point, D

ninth_and_mass = Point(-95.23592948913574, 38.96753407043678)
user_loc = Point(-95.23455619812012, 38.97240128290697)
Expand Down Expand Up @@ -365,7 +363,7 @@ distance information on the results & nothing to sort by.
Examples::

from haystack.query import SearchQuerySet
from haystack.utils.geo import Point, D
from django.contrib.gis.geos import Point, D

ninth_and_mass = Point(-95.23592948913574, 38.96753407043678)
downtown_bottom_left = Point(-95.23947, 38.9637903)
Expand Down
14 changes: 13 additions & 1 deletion docs/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ the following:
Solr
~~~~

Example::
Example (Solr 4.X)::

HAYSTACK_CONNECTIONS = {
'default': {
Expand All @@ -123,6 +123,17 @@ Example::
},
}

Example (Solr 6.X)::

HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.solr_backend.SolrEngine',
'URL': 'http://127.0.0.1:8983/solr/tester', # Assuming you created a core named 'tester' as described in installing search engines.
'ADMIN_URL': 'http://127.0.0.1:8983/solr/admin/cores'
# ...or for multicore...
# 'URL': 'http://127.0.0.1:8983/solr/mysite',
},
}

Elasticsearch
~~~~~~~~~~~~~
Expand All @@ -147,6 +158,7 @@ Example (ElasticSearch 2.x)::
},
}


Whoosh
~~~~~~

Expand Down
3 changes: 2 additions & 1 deletion haystack/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
)
if hasattr(settings, "HAYSTACK_INCLUDE_SPELLING"):
raise ImproperlyConfigured(
"The HAYSTACK_INCLUDE_SPELLING setting is now a per-backend setting & belongs in HAYSTACK_CONNECTIONS."
"The HAYSTACK_INCLUDE_SPELLING setting is now a per-backend setting"
" & belongs in HAYSTACK_CONNECTIONS."
)


Expand Down
43 changes: 13 additions & 30 deletions haystack/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,13 @@
from haystack.utils import get_model_ct_tuple


def list_max_show_all(changelist):
"""
Returns the maximum amount of results a changelist can have for the
"Show all" link to be displayed in a manner compatible with both Django
1.4 and 1.3. See Django ticket #15997 for details.
"""
try:
# This import is available in Django 1.3 and below
from django.contrib.admin.views.main import MAX_SHOW_ALL_ALLOWED

return MAX_SHOW_ALL_ALLOWED
except ImportError:
return changelist.list_max_show_all


class SearchChangeList(ChangeList):
def __init__(self, **kwargs):
self.haystack_connection = kwargs.pop("haystack_connection", "default")
super(SearchChangeList, self).__init__(**kwargs)

def get_results(self, request):
if not SEARCH_VAR in request.GET:
if SEARCH_VAR not in request.GET:
return super(SearchChangeList, self).get_results(request)

# Note that pagination is 0-based, not 1-based.
Expand All @@ -54,7 +39,7 @@ def get_results(self, request):
SearchQuerySet(self.haystack_connection).models(self.model).all().count()
)

can_show_all = result_count <= list_max_show_all(self)
can_show_all = result_count <= self.list_max_show_all
multi_page = result_count > self.list_per_page

# Get the list of objects to display on this page.
Expand Down Expand Up @@ -83,20 +68,21 @@ def changelist_view(self, request, extra_context=None):
if not self.has_change_permission(request, None):
raise PermissionDenied

if not SEARCH_VAR in request.GET:
if SEARCH_VAR not in request.GET:
# Do the usual song and dance.
return super(SearchModelAdminMixin, self).changelist_view(
request, extra_context
)

# Do a search of just this model and populate a Changelist with the
# returned bits.
if (
not self.model
in connections[self.haystack_connection]
indexed_models = (
connections[self.haystack_connection]
.get_unified_index()
.get_indexed_models()
):
)

if self.model not in indexed_models:
# Oops. That model isn't being indexed. Return the usual
# behavior instead.
return super(SearchModelAdminMixin, self).changelist_view(
Expand All @@ -119,15 +105,13 @@ def changelist_view(self, request, extra_context=None):
"list_select_related": self.list_select_related,
"list_per_page": self.list_per_page,
"list_editable": self.list_editable,
"list_max_show_all": self.list_max_show_all,
"model_admin": self,
}

# Django 1.4 compatibility.
if hasattr(self, "list_max_show_all"):
kwargs["list_max_show_all"] = self.list_max_show_all

if hasattr(self, 'get_sortable_by'): # Django 2.1+
kwargs["sortable_by"] = self.get_sortable_by(request)
changelist = SearchChangeList(**kwargs)
formset = changelist.formset = None
changelist.formset = None
media = self.media

# Build the action form and populate it with available actions.
Expand Down Expand Up @@ -160,8 +144,7 @@ def changelist_view(self, request, extra_context=None):
"cl": changelist,
"media": media,
"has_add_permission": self.has_add_permission(request),
# More Django 1.4 compatibility
"root_path": getattr(self.admin_site, "root_path", None),
"opts": changelist.opts,
"app_label": self.model._meta.app_label,
"action_form": action_form,
"actions_on_top": self.actions_on_top,
Expand Down
2 changes: 1 addition & 1 deletion haystack/backends/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import copy
import six
from copy import deepcopy
from time import time
from django.conf import settings
from django.db.models import Q
from django.db.models.base import ModelBase
from django.utils import six
from django.utils import tree
from django.utils.encoding import force_text

Expand Down
Loading