Overrided searchfilterbackend

This commit is contained in:
evgeniy-st 2019-09-09 12:00:53 +03:00
parent 43804ae5ab
commit b326d7b8fd
2 changed files with 96 additions and 22 deletions

View File

@ -0,0 +1,82 @@
"""Search indexes filters."""
from elasticsearch_dsl.query import Q
from django_elasticsearch_dsl_drf.filter_backends import SearchFilterBackend
from utils.models import get_current_language
class CustomSearchFilterBackend(SearchFilterBackend):
"""Custom SearchFilterBackend."""
@staticmethod
def get_field_name(view, field):
field_name = field
if hasattr(view, 'search_fields') and hasattr(view, 'translated_search_fields'):
if field in view.translated_search_fields:
field_name = f'{field}.{get_current_language()}'
return field_name
def construct_search(self, request, view):
"""Construct search.
We have to deal with two types of structures:
Type 1:
>>> search_fields = (
>>> 'title',
>>> 'description',
>>> 'summary',
>>> )
Type 2:
>>> search_fields = {
>>> 'title': {'boost': 2},
>>> 'description': None,
>>> 'summary': None,
>>> }
:param request: Django REST framework request.
:param queryset: Base queryset.
:param view: View.
:type request: rest_framework.request.Request
:type queryset: elasticsearch_dsl.search.Search
:type view: rest_framework.viewsets.ReadOnlyModelViewSet
:return: Updated queryset.
:rtype: elasticsearch_dsl.search.Search
"""
query_params = self.get_search_query_params(request)
__queries = []
for search_term in query_params:
__values = self.split_lookup_name(search_term, 1)
__len_values = len(__values)
if __len_values > 1:
field, value = __values
if field in view.search_fields:
# Initial kwargs for the match query
field_kwargs = {self.get_field_name(view, field): {'query': value}}
# In case if we deal with structure 2
if isinstance(view.search_fields, dict):
extra_field_kwargs = view.search_fields[field]
if extra_field_kwargs:
field_kwargs[self.get_field_name(view, field)].update(extra_field_kwargs)
# The match query
__queries.append(
Q("match", **field_kwargs)
)
else:
for field in view.search_fields:
# Initial kwargs for the match query
field_kwargs = {self.get_field_name(view, field): {'query': search_term}}
# In case if we deal with structure 2
if isinstance(view.search_fields, dict):
extra_field_kwargs = view.search_fields[field]
if extra_field_kwargs:
field_kwargs[self.get_field_name(view, field)].update(extra_field_kwargs)
# The match query
__queries.append(
Q("match", **field_kwargs)
)
return __queries

View File

@ -2,22 +2,9 @@
from rest_framework import permissions
from django_elasticsearch_dsl_drf.viewsets import BaseDocumentViewSet
from django_elasticsearch_dsl_drf.pagination import PageNumberPagination
from search_indexes import serializers
from search_indexes import serializers, filters
from search_indexes.documents import NewsDocument
# from django_elasticsearch_dsl_drf.constants import (
# LOOKUP_QUERY_IN,
# LOOKUP_QUERY_GT,
# )
#
from django_elasticsearch_dsl_drf.filter_backends import (
FilteringFilterBackend,
IdsFilterBackend,
OrderingFilterBackend,
SearchFilterBackend,
DefaultOrderingFilterBackend,
)
class NewsDocumentViewSet(BaseDocumentViewSet):
"""News document ViewSet."""
@ -28,13 +15,18 @@ class NewsDocumentViewSet(BaseDocumentViewSet):
permission_classes = (permissions.AllowAny,)
serializer_class = serializers.NewsDocumentSerializer
ordering = ('id',)
#
filter_backends = [
# DefaultOrderingFilterBackend,
# FilteringFilterBackend,
SearchFilterBackend,
filters.CustomSearchFilterBackend,
]
#
# search_fields = (
# 'playlist', 'title', 'subtitle', 'description'
# )
search_fields = (
'title',
'subtitle',
'description',
)
translated_search_fields = (
'title',
'subtitle',
'description',
)