Source code for api.users.filters

from elasticsearch_dsl import Q
from rest_framework.filters import BaseFilterBackend
from rest_framework.settings import api_settings

from apps.users.documents import UserDocument


[docs] class UserElasticsearchFilter(BaseFilterBackend): """ Filter for performing user search using Elasticsearch. Executes search on username, first_name, and last_name with different weights. """
[docs] def construct_query(self, search_param): """ Constructs a combined Elasticsearch query from various parts. :param search_param: The search parameter entered by the user. :return: A combined Elasticsearch query. """ # Queries for each parameter username_query = Q("match", username={"query": search_param, "fuzziness": "AUTO", "boost": 4}) first_name_query = Q("match", first_name={"query": search_param, "fuzziness": "AUTO", "boost": 3}) last_name_query = Q("match", last_name={"query": search_param, "fuzziness": "AUTO", "boost": 2}) # Combine the queries combined_query = Q( "bool", should=[ username_query, first_name_query, last_name_query, ], ) return combined_query
[docs] def filter_queryset(self, request, queryset, view): """ Filters a QuerySet based on the search parameters in the request. :param request: HTTP request object. :param queryset: Initial QuerySet. :param view: The view that calls this method. :return: Updated QuerySet. """ search_param = request.query_params.get("search") offset = int(request.query_params.get("offset", 0)) limit = int(request.query_params.get("limit", api_settings.PAGE_SIZE)) if search_param: combined_query = self.construct_query(search_param) search = UserDocument.search().query(combined_query) total_results = search.count() if offset >= total_results: return queryset.none() end = offset + limit search = search[offset:end] queryset = search.to_queryset() queryset.search_count = total_results return queryset