Hi thanks for your help in advance!
On a wagtail 2.2.2 project I recently added search functionality with PostgreSQL search backend. It was working great until I tried running a search on a filtered PageQuerySet
by given tag whichs throws this error:
FilterFieldError at /blog/tags/tag_slug/
Cannot filter search results with field "tag_id". Please add index.FilterField('tag_id') to BlogPost.search_fields.
Django Version: 2.0.13
Python Version: 3.6.8
...
File "/path/to/env/lib/python3.6/site-packages/wagtail/search/queryset.py" in search
12. operator=operator, order_by_relevance=order_by_relevance, partial_match=partial_match)
File "/path/to/env/lib/python3.6/site-packages/wagtail/search/backends/base.py" in search
371. partial_match=partial_match,
File "/path/to/env/lib/python3.6/site-packages/wagtail/search/backends/base.py" in _search
359. search_query.check()
File "/path/to/env/lib/python3.6/site-packages/wagtail/search/backends/base.py" in check
157. self._get_filters_from_where_node(self.queryset.query.where, check_only=True)
File "/path/to/env/lib/python3.6/site-packages/wagtail/search/backends/base.py" in _get_filters_from_where_node
108. child_filters = [self._get_filters_from_where_node(child) for child in where_node.children]
File "/path/to/env/lib/python3.6/site-packages/wagtail/search/backends/base.py" in <listcomp>
108. child_filters = [self._get_filters_from_where_node(child) for child in where_node.children]
File "/path/to/env/lib/python3.6/site-packages/wagtail/search/backends/base.py" in _get_filters_from_where_node
100. return self._process_filter(field_attname, lookup, value, check_only=check_only)
File "/path/to/env/lib/python3.6/site-packages/wagtail/search/backends/base.py" in _process_filter
73. field_name=field_attname
Exception Type: FilterFieldError at /trust-worthy/tags/presentation/
Exception Value: Cannot filter search results with field "tag_id". Please add index.FilterField('tag_id') to BlogPost.search_fields.
I added the FilterField
to the BlogPost model search_fields like it said and it seems to be working fine with correct search results returned on the filtered set. The only problem now is that every time Django boots up it shows this warning:
System check identified some issues:
WARNINGS:
blog.BlogPost: BlogPost.search_fields contains non-existent field 'tag_id'
Here is a basic summary of how the relevant models are setup:
from wagtail.core.models import Page
from wagtail.search import index
from taggit.models import Tag, TaggedItemBase
from modelcluster.contrib.taggit import ClusterTaggableManager
from modelcluster.fields import ParentalKey
class BlogIndex(Page):
get_context(self, request):
context = super().get_context(request)
tag = Tag.objects.get(slug=some_tag_slug)
pages = BlogPost.objects.descendant_of(self)\
.live().public().order_by('-date')
# The above <PageQuerySet> works fine to search
# until I add this valid working filter:
pages = pages.filter(tags=tag)
# ...which causes the original error when searching that is
# fixed by adding `tag_id` FilterField to BlogPost.search_fields
pages = pages.search(some_search_query)
# `pages` is now valid <PostgresSearchResults>
context['pages'] = pages
return context
class BlogPostTag(TaggedItemBase):
content_object = ParentalKey('blog.BlogPost', related_name='tagged_items')
class BlogPost(Page):
search_fields = Page.search_fields + [
index.FilterField('tag_id'), # This fixes the error but causes the warning
]
tags = ClusterTaggableManager(through=BlogPostTag, blank=True)
My question is -- what am I doing wrong to cause the warning about the non-existent field? The search works fine now on the filtered list, but it's also true that tag_id
is not a field on the BlogPost model. Is there another proper way to fix the Cannot filter search results
error and receive the same results?