diff --git a/bakerydemo/base/models.py b/bakerydemo/base/models.py index f8e39e8..3a3e66d 100644 --- a/bakerydemo/base/models.py +++ b/bakerydemo/base/models.py @@ -44,6 +44,11 @@ class People(ClusterableModel): ImageChooserPanel('image') ] + search_fields = Page.search_fields + [ + index.SearchField('first_name'), + index.SearchField('last_name'), + ] + def __str__(self): return self.first_name + " " + self.last_name diff --git a/bakerydemo/blog/models.py b/bakerydemo/blog/models.py index 2e08d01..210f1c1 100644 --- a/bakerydemo/blog/models.py +++ b/bakerydemo/blog/models.py @@ -19,7 +19,7 @@ from wagtail.wagtailimages.edit_handlers import ImageChooserPanel from wagtail.wagtailcore.fields import StreamField from wagtail.wagtailcore.models import Page, Orderable from wagtail.wagtailsnippets.edit_handlers import SnippetChooserPanel - +from wagtail.wagtailsearch import index from bakerydemo.base.blocks import BaseStreamBlock @@ -75,6 +75,11 @@ class BlogPage(Page): FieldPanel('tags'), ] + search_fields = Page.search_fields + [ + index.SearchField('title'), + index.SearchField('body'), + ] + def authors(self): ''' Returns the BlogPage's related People diff --git a/bakerydemo/locations/models.py b/bakerydemo/locations/models.py index 9c4ba66..3c469d9 100644 --- a/bakerydemo/locations/models.py +++ b/bakerydemo/locations/models.py @@ -111,7 +111,7 @@ class LocationPage(Page): ] def __str__(self): - return self.name + return self.title def opening_hours(self): hours = self.hours_of_operation.all() diff --git a/bakerydemo/search/__init__.py b/bakerydemo/search/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bakerydemo/search/views.py b/bakerydemo/search/views.py new file mode 100644 index 0000000..78bbff3 --- /dev/null +++ b/bakerydemo/search/views.py @@ -0,0 +1,58 @@ +from django.shortcuts import render +from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger + +from wagtail.wagtailcore.models import Page +from wagtail.wagtailsearch.models import Query + +from bakerydemo.blog.models import BlogPage +from bakerydemo.breads.models import BreadPage +from bakerydemo.locations.models import LocationPage +from bakerydemo.base.models import People + + +def search(request): + # Search + search_query = request.GET.get('query', None) + if search_query: + ''' + Because we can't use ElasticSearch for the demo, we use the native db search. + But native DB search can't search specific fields in our models on a `Page` query. + So for demo purposes ONLY, we hard-code in the model names we want to search. + In production, use ElasticSearch and a simplified search query, per + http://docs.wagtail.io/en/v1.8.1/topics/search/searching.html + ''' + + blog_results = BlogPage.objects.live().search(search_query) + blog_page_ids = [p.page_ptr.id for p in blog_results] + + bread_results = BreadPage.objects.live().search(search_query) + bread_page_ids = [p.page_ptr.id for p in bread_results] + + location_results = LocationPage.objects.live().search(search_query) + location_result_ids = [p.page_ptr.id for p in location_results] + + page_ids = blog_page_ids + bread_page_ids + location_result_ids + search_results = Page.objects.live().filter(id__in=page_ids) + + query = Query.get(search_query) + + # Record hit + query.add_hit() + + else: + search_results = Page.objects.none() + + # Pagination + page = request.GET.get('page', 1) + paginator = Paginator(search_results, 10) + try: + search_results = paginator.page(page) + except PageNotAnInteger: + search_results = paginator.page(1) + except EmptyPage: + search_results = paginator.page(paginator.num_pages) + + return render(request, 'search/search_results.html', { + 'search_query': search_query, + 'search_results': search_results, + }) diff --git a/bakerydemo/settings/base.py b/bakerydemo/settings/base.py index fafcc1e..ba71042 100644 --- a/bakerydemo/settings/base.py +++ b/bakerydemo/settings/base.py @@ -35,7 +35,7 @@ INSTALLED_APPS = [ 'bakerydemo.blog', 'bakerydemo.breads', 'bakerydemo.locations', - # 'bakerydemo.search', + 'bakerydemo.search', 'wagtail.contrib.wagtailsearchpromotions', 'wagtail.wagtailforms', @@ -168,6 +168,7 @@ WAGTAILSEARCH_BACKENDS = { }, } + # Wagtail settings WAGTAIL_SITE_NAME = "bakerydemo" diff --git a/bakerydemo/templates/base.html b/bakerydemo/templates/base.html index ead2ce8..5a34fca 100755 --- a/bakerydemo/templates/base.html +++ b/bakerydemo/templates/base.html @@ -20,7 +20,7 @@ {% endif %} {% endblock %} - + @@ -65,6 +65,11 @@ diff --git a/bakerydemo/templates/search/search_box.html b/bakerydemo/templates/search/search_box.html new file mode 100644 index 0000000..47add30 --- /dev/null +++ b/bakerydemo/templates/search/search_box.html @@ -0,0 +1,14 @@ +
+
+
+
+ +
+ +
+
+
+
+
diff --git a/bakerydemo/templates/search/search_results.html b/bakerydemo/templates/search/search_results.html new file mode 100644 index 0000000..9da1b18 --- /dev/null +++ b/bakerydemo/templates/search/search_results.html @@ -0,0 +1,34 @@ +{% extends "base.html" %} +{% load wagtailcore_tags %} + +{% block title %}Search{% if search_results %} results{% endif %}{% endblock %} + +{% block content %} + +

+ Search results{% if request.GET.query %} for “{{ request.GET.query }}”{% endif %} +

+ {% if search_results %} + + {% elif search_query %} + No results found + {% else %} + You didn’t search for anything! + {% endif %} +{% endblock %} diff --git a/bakerydemo/urls.py b/bakerydemo/urls.py index 16e6c27..f8368e2 100644 --- a/bakerydemo/urls.py +++ b/bakerydemo/urls.py @@ -6,7 +6,7 @@ from wagtail.wagtailadmin import urls as wagtailadmin_urls from wagtail.wagtaildocs import urls as wagtaildocs_urls from wagtail.wagtailcore import urls as wagtail_urls -# from bakerydemo.search import views as search_views +from bakerydemo.search import views as search_views urlpatterns = [ @@ -15,7 +15,7 @@ urlpatterns = [ url(r'^admin/', include(wagtailadmin_urls)), url(r'^documents/', include(wagtaildocs_urls)), - # url(r'^search/$', search_views.search, name='search'), + url(r'^search/$', search_views.search, name='search'), ] diff --git a/readme.md b/readme.md index 69529fd..f39514f 100644 --- a/readme.md +++ b/readme.md @@ -46,3 +46,11 @@ With PIP installed run the following commands: ./manage.py load_initial_data ./manage.py createsuperuser ./manage.py runserver + +### Note on demo search: + +Because we can't (easily) use ElasticSearch for this demo, we use wagtail's native DB search. +However, native DB search can't search specific fields in our models on a generalized `Page` query. +So for demo purposes ONLY, we hard-code the model names we want to search into `search.views`, which is +not ideal. In production, use ElasticSearch and a simplified search query, per +http://docs.wagtail.io/en/v1.8.1/topics/search/searching.html