mirror of
https://github.com/Hopiu/wagtail.git
synced 2026-05-03 21:14:46 +00:00
Added new search configuration format
This commit is contained in:
parent
1a3558cabd
commit
bba9d4faf2
6 changed files with 94 additions and 51 deletions
|
|
@ -4,27 +4,20 @@ from django.contrib.contenttypes.models import ContentType
|
|||
from django.db.models import Count
|
||||
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
||||
|
||||
from wagtail.wagtailsearch import Indexed, get_search_backend
|
||||
from wagtail.wagtailsearch import indexed
|
||||
from wagtail.wagtailsearch.backends import get_search_backend
|
||||
|
||||
|
||||
class TagSearchable(Indexed):
|
||||
class TagSearchable(indexed.Indexed):
|
||||
"""
|
||||
Mixin to provide a 'search' method, searching on the 'title' field and tags,
|
||||
for models that provide those things.
|
||||
"""
|
||||
|
||||
indexed_fields = {
|
||||
'title': {
|
||||
'type': 'string',
|
||||
'analyzer': 'edgengram_analyzer',
|
||||
'boost': 10,
|
||||
},
|
||||
'get_tags': {
|
||||
'type': 'string',
|
||||
'analyzer': 'edgengram_analyzer',
|
||||
'boost': 10,
|
||||
},
|
||||
}
|
||||
search_fields = (
|
||||
indexed.SearchField('title', partial_match=True, boost=10),
|
||||
indexed.SearchField('get_tags', partial_match=True, boost=10)
|
||||
)
|
||||
|
||||
@property
|
||||
def get_tags(self):
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ from treebeard.mp_tree import MP_Node
|
|||
from wagtail.wagtailcore.utils import camelcase_to_underscore
|
||||
from wagtail.wagtailcore.query import PageQuerySet
|
||||
|
||||
from wagtail.wagtailsearch import Indexed, get_search_backend
|
||||
from wagtail.wagtailsearch import indexed
|
||||
from wagtail.wagtailsearch.backends import get_search_backend
|
||||
|
||||
|
||||
class SiteManager(models.Manager):
|
||||
|
|
@ -260,7 +261,7 @@ class PageBase(models.base.ModelBase):
|
|||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Page(six.with_metaclass(PageBase, MP_Node, ClusterableModel, Indexed)):
|
||||
class Page(six.with_metaclass(PageBase, MP_Node, ClusterableModel, indexed.Indexed)):
|
||||
title = models.CharField(max_length=255, help_text=_("The page title as you'd like it to be seen by the public"))
|
||||
slug = models.SlugField(help_text=_("The name of the page as it will appear in URLs e.g http://domain.com/blog/[my-slug]/"))
|
||||
# TODO: enforce uniqueness on slug field per parent (will have to be done at the Django
|
||||
|
|
@ -279,21 +280,11 @@ class Page(six.with_metaclass(PageBase, MP_Node, ClusterableModel, Indexed)):
|
|||
expire_at = models.DateTimeField(verbose_name=_("Expiry date/time"), help_text=_("Please add a date-time in the form YYYY-MM-DD hh:mm."), blank=True, null=True)
|
||||
expired = models.BooleanField(default=False, editable=False)
|
||||
|
||||
indexed_fields = {
|
||||
'title': {
|
||||
'type': 'string',
|
||||
'analyzer': 'edgengram_analyzer',
|
||||
'boost': 100,
|
||||
},
|
||||
'live': {
|
||||
'type': 'boolean',
|
||||
'index': 'not_analyzed',
|
||||
},
|
||||
'path': {
|
||||
'type': 'string',
|
||||
'index': 'not_analyzed',
|
||||
},
|
||||
}
|
||||
search_fields = (
|
||||
indexed.SearchField('title', partial_match=True, boost=100),
|
||||
indexed.FilterField('live'),
|
||||
indexed.FilterField('path'),
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Page, self).__init__(*args, **kwargs)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||
from django.utils.encoding import python_2_unicode_compatible
|
||||
|
||||
from wagtail.wagtailadmin.taggable import TagSearchable
|
||||
from wagtail.wagtailsearch import indexed
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
|
|
@ -23,14 +24,9 @@ class Document(models.Model, TagSearchable):
|
|||
|
||||
tags = TaggableManager(help_text=None, blank=True, verbose_name=_('Tags'))
|
||||
|
||||
indexed_fields = {
|
||||
'uploaded_by_user_id': {
|
||||
'type': 'integer',
|
||||
'store': 'yes',
|
||||
'indexed': 'no',
|
||||
'boost': 0,
|
||||
},
|
||||
}
|
||||
search_fields = TagSearchable.search_fields + (
|
||||
indexed.FilterField('uploaded_by_user'),
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ from unidecode import unidecode
|
|||
|
||||
from wagtail.wagtailadmin.taggable import TagSearchable
|
||||
from wagtail.wagtailimages.backends import get_image_backend
|
||||
from wagtail.wagtailsearch import indexed
|
||||
from .utils import validate_image_format
|
||||
|
||||
|
||||
|
|
@ -48,14 +49,9 @@ class AbstractImage(models.Model, TagSearchable):
|
|||
|
||||
tags = TaggableManager(help_text=None, blank=True, verbose_name=_('Tags'))
|
||||
|
||||
indexed_fields = {
|
||||
'uploaded_by_user_id': {
|
||||
'type': 'integer',
|
||||
'store': 'yes',
|
||||
'indexed': 'no',
|
||||
'boost': 0,
|
||||
},
|
||||
}
|
||||
search_fields = TagSearchable.search_fields + (
|
||||
indexed.FilterField('uploaded_by_user'),
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
|
|
|||
|
|
@ -35,6 +35,11 @@ class Indexed(object):
|
|||
|
||||
@classmethod
|
||||
def indexed_get_indexed_fields(cls):
|
||||
# New way
|
||||
if hasattr(cls, 'search_fields'):
|
||||
return dict((field.get_attname(cls), field.to_dict(cls)) for field in cls.search_fields)
|
||||
|
||||
# Old way
|
||||
# Get indexed fields for this class as dictionary
|
||||
indexed_fields = cls.indexed_fields
|
||||
if isinstance(indexed_fields, dict):
|
||||
|
|
@ -83,3 +88,58 @@ class Indexed(object):
|
|||
return doc
|
||||
|
||||
indexed_fields = ()
|
||||
|
||||
|
||||
class BaseField(object):
|
||||
def __init__(self, field_name, **kwargs):
|
||||
self.field_name = field_name
|
||||
self.kwargs = kwargs
|
||||
|
||||
def get_field(self, cls):
|
||||
return cls._meta.get_field_by_name(self.field_name)[0]
|
||||
|
||||
def get_attname(self, cls):
|
||||
try:
|
||||
field = self.get_field(cls)
|
||||
return field.attname
|
||||
except models.fields.FieldDoesNotExist:
|
||||
return self.field_name
|
||||
|
||||
def to_dict(self, cls):
|
||||
dic = {
|
||||
'type': 'string'
|
||||
}
|
||||
|
||||
if 'es_extra' in self.kwargs:
|
||||
for key, value in self.kwargs['es_extra'].items():
|
||||
dic[key] = value
|
||||
|
||||
return dic
|
||||
|
||||
|
||||
class SearchField(BaseField):
|
||||
def __init__(self, field_name, boost=None, partial_match=False, **kwargs):
|
||||
super(SearchField, self).__init__(field_name, **kwargs)
|
||||
self.boost = boost
|
||||
self.partial_match = partial_match
|
||||
|
||||
def to_dict(self, cls):
|
||||
dic = super(SearchField, self).to_dict(cls)
|
||||
|
||||
if self.boost and 'boost' not in dic:
|
||||
dic['boost'] = self.boost
|
||||
|
||||
if self.partial_match and 'analyzer' not in dic:
|
||||
dic['analyzer'] = 'edgengram_analyzer'
|
||||
|
||||
return dic
|
||||
|
||||
|
||||
class FilterField(BaseField):
|
||||
def to_dict(self, cls):
|
||||
dic = super(FilterField, self).to_dict(cls)
|
||||
|
||||
if 'index' not in dic:
|
||||
dic['index'] = 'not_analyzed'
|
||||
|
||||
return dic
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from django.db import models
|
|||
from django.utils import timezone
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
|
||||
from wagtail.wagtailsearch.indexed import Indexed
|
||||
from wagtail.wagtailsearch import indexed
|
||||
from wagtail.wagtailsearch.utils import normalise_query_string, MAX_QUERY_STRING_LENGTH
|
||||
|
||||
|
||||
|
|
@ -82,12 +82,17 @@ class EditorsPick(models.Model):
|
|||
|
||||
# Used for tests
|
||||
|
||||
class SearchTest(models.Model, Indexed):
|
||||
class SearchTest(models.Model, indexed.Indexed):
|
||||
title = models.CharField(max_length=255)
|
||||
content = models.TextField()
|
||||
live = models.BooleanField(default=False)
|
||||
|
||||
indexed_fields = ("title", "content", "callable_indexed_field", "live")
|
||||
search_fields = (
|
||||
indexed.SearchField('title'),
|
||||
indexed.SearchField('content'),
|
||||
indexed.SearchField('callable_indexed_field'),
|
||||
indexed.SearchField('live'),
|
||||
)
|
||||
|
||||
def callable_indexed_field(self):
|
||||
return "Callable"
|
||||
|
|
@ -96,4 +101,6 @@ class SearchTest(models.Model, Indexed):
|
|||
class SearchTestChild(SearchTest):
|
||||
extra_content = models.TextField()
|
||||
|
||||
indexed_fields = "extra_content"
|
||||
search_fields = SearchTest.search_fields + (
|
||||
indexed.SearchField('extra_content'),
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue