Wagtail: Filtering a search on a ManyToMany through model

Viewed 1007

In a Wagtail-based site, I have an ArticlePage model which is related to an Author snippet model in a many-to-many relationship like this:

from django.db import models
from modelcluster.fields import ParentalKey
from wagtail.core.models import Orderable, Page
from wagtail.search import index
from wagtail.snippets.models import register_snippet

class ArticlePage(Page):
    search_fields = Page.search_fields + [
       index.FilterField('author_id'),
    ]

@register_snippet
class Author(models.Model):
    name = models.CharField(max_length=255, blank=False)

class ArticleAuthorRelationship(Orderable, models.Model):
    author = models.ForeignKey('Author', on_delete=models.CASCADE, related_name='articles')
    page = ParentalKey('ArticlePage', on_delete=models.CASCADE, related_name='authors')

I want to be able to search ArticlePages and filter them by a particular Author, which I can do like this:

author = Author.objects.get(id=1)

articles = ArticlePage.objects.live() \
                              .filter(authors__author=author) \
                              .search('football')

But in the dev server logs I get this warning:

articles.ArticlePage: ArticlePage.search_fields contains non-existent field ‘author_id’

My question is: Am I doing this right? It works, but the warning makes me think there might be a more correct way to achieve the same result.

I have also tried using FilterField('authors'), which stops the warning, but I can't work out how to filter on that.

1 Answers

the correct way was explained in the documentation

here an example that is shared in the official documentation:

from wagtail.search import index

class Book(models.Model, index.Indexed):
    ...

    search_fields = [
        index.SearchField('title'),
        index.FilterField('published_date'),

        index.RelatedFields('author', [
            index.SearchField('name'),
            index.FilterField('date_of_birth'),
        ]),
    ]

so in your case, you should write:

class ArticlePage(Page):
    search_fields = Page.search_fields + [
       index.RelatedFields(
            "author", [index.SearchField("id")]
        ),
    ]

let me know if it is working

Related