Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Possibility to query multiple fields for autocompleting #120

Open
rinti opened this issue Jun 3, 2022 · 3 comments
Open

Possibility to query multiple fields for autocompleting #120

rinti opened this issue Jun 3, 2022 · 3 comments

Comments

@rinti
Copy link

rinti commented Jun 3, 2022

Right know we can supply which field the autocomplete should use like so:
autocomplete_search_field = "title_en"

I'm proposing we should allow querying more than one field. E.g.:
autocomplete_search_field = "title_en,title_sv"

Currently I monkey patched this in our project, but I'd be happy to contribute if this is something you'd want in this package.

@R-baji
Copy link

R-baji commented Jan 16, 2023

I came here to open an issue about suggesting the exact main thing, as I've also patched this in our project, and will gladly submit a PR for it

@chrisdao93
Copy link

Could you please show me how you have patched it? Thank you so much in advance.

@rinti
Copy link
Author

rinti commented Sep 7, 2023

@chrisdao93 I did it like this:

def autocomplete_search(request):
    search_query = request.GET.get("query", "")
    target_model = request.GET.get("type", "wagtailcore.Page")
    try:
        model = apps.get_model(target_model)
    except Exception:
        return HttpResponseBadRequest()

    try:
        limit = int(request.GET.get("limit", 100))
    except ValueError:
        return HttpResponseBadRequest()

    field_name = getattr(model, "autocomplete_search_field", "title")
    multi_field_names = getattr(model, "autocomplete_search_multifields", None)

    if multi_field_names:
        filter_q = Q()
        for field in multi_field_names.split(","):
            filter_kwargs = dict()
            filter_kwargs[field + "__icontains"] = search_query
            filter_q |= Q(**filter_kwargs)
        queryset = model.objects.filter(filter_q)
    else:
        filter_kwargs = dict()
        filter_kwargs[field_name + "__icontains"] = search_query
        queryset = model.objects.filter(**filter_kwargs)

    if getattr(queryset, "live", None):
        # Non-Page models like Snippets won't have a live/published status
        # and thus should not be filtered with a call to `live`.
        queryset = queryset.live()

    exclude = request.GET.get("exclude", "")
    if exclude:
        exclusions = [unquote(item) for item in exclude.split(",") if item]
        queryset = queryset.exclude(pk__in=exclusions)

    results = map(wagtailautocomplete.views.render_page, queryset[:limit])
    return JsonResponse(dict(items=list(results)))

Then add this url:

urlpatterns += [
    path(f"cms/autocomplete/search/", autocomplete_search),  # our own view
    path(f"cms/autocomplete/", include(autocomplete_admin_urls)),
]

Then it's possible to

class MyPage(Page):
    # ...
    autocomplete_search_multifields = "title_en,title_sv"

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants