Skip to content
New issue

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

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

Already on GitHub? Sign in 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"

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

No branches or pull requests

3 participants