djangowagtailwagtail-snippetwagtail-search

SearchFieldError - Cannot search with field "body". Please add index.SearchField('body') to Page.search_fields


I have a elasticsearch backend (7.14.0) and wagtail (2.14.1) and I want to include a fulltext-search at the body field of my page. When search something in frontend, I get

SearchFieldError at /search/
Cannot search with field "body". Please add index.SearchField('body') to 
Page.search_fields.
Request Method: GET
Request URL:    https://my.site/search/?query=impres
Django Version: 3.2.4
Exception Type: SearchFieldError
Exception Value:    
Cannot search with field "body". Please add index.SearchField('body') to         
Page.search_fields.
Exception Location: /var/www/vhosts/my.site/dev4/venv/lib/python3.6/site-packages/wagtail/search/backends/base.py, line 163, in check
Python Executable:  /var/www/vhosts/my.site/dev4/venv/bin/python
Python Version: 3.6.9
Python Path:    
['/var/www/vhosts/my.site/dev4/venv/bin',
 '/var/www/vhosts/my.site/dev4/mysite/mysite',
 '/var/www/vhosts/my.site/dev4/mysite',
 '/var/www/vhosts/my.site/dev4',
 '/usr/share/passenger/helper-scripts',
 '/usr/lib/python36.zip',
 '/usr/lib/python3.6',
 '/usr/lib/python3.6/lib-dynload',
 '/var/www/vhosts/my.site/dev4/venv/lib/python3.6/site-packages']
Server time:    Mon, 23 Aug 2021 05:24:18 +0000

my views.py:

from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.template.response import TemplateResponse

from wagtail.core.models import Page
from wagtail.search.models import Query




def search(request):
    search_query = request.GET.get('query', None)
    page = request.GET.get('page', 1)

    # Search
    if search_query:
        #search_results = Page.objects.live().search(search_query)
        # exclude some search results
        search_results = Page.objects.live()\
        .exclude(title='Sie sind nun ausgeloggt.')\
        .exclude(title='Sie sind nun eingeloggt.')\
        .exclude(title='Passwort erfolgreich geändert.')\
        .search(search_query, fields=["title", "body"])

        query = Query.get(search_query)

        # Record hit
        query.add_hit()
    else:
        search_results = Page.objects.none()

    # Pagination
    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 TemplateResponse(request, 'search/search.html', {
        'search_query': search_query,
        'search_results': search_results,
    })

my models.py:

from django.db import models

from wagtail.core.models import Page
from wagtail.core.fields import RichTextField
from wagtail.admin.edit_handlers import FieldPanel

from wagtail.search import index


class HomePage(Page):
    body = RichTextField(blank=True)

    content_panels = Page.content_panels + [
        FieldPanel('body', classname="full"),
    ]

    # Search index configuration

    search_fields = Page.search_fields + [ # Inherit search_fields from Page
        index.SearchField('body'),
    ]

So I already added index.SearchField('body') to Page.search_fields and can't find any type-o's. Any idea what I'm doing wrong?


Solution

  • Setting fields=["title", "body"] on the search query doesn't work here, because your search query is being run on the basic Page model (which is the right thing to do if you want your search to cover all page types) - here the body field is specific to the HomePage model, and so it isn't recognised more generally.

    Typically the set of fields is going to vary from one page type to another, and you'd only include fields=[...] on a search if you're looking for something specific within one particular page type:

    EventPage.objects.search('london', fields=['location'])
    

    For a general-purpose search, you should leave out the fields=[...] argument when searching - it will then search across all fields that have been named as SearchFields in all page types. You should keep the index.SearchField('body') line in place on the HomePage definition, and make sure you've re-run ./manage.py update_index since adding it.