Skip to content

Commit

Permalink
Add unaccent to SearchFilter
Browse files Browse the repository at this point in the history
  • Loading branch information
mgaligniana committed Apr 15, 2024
1 parent 9864c47 commit f8825ba
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 2 deletions.
2 changes: 2 additions & 0 deletions docs/api-guide/filtering.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ The search behavior may be specified by prefixing field names in `search_fields`
| `$` | `iregex` | Regex search. |
| `@` | `search` | Full-text search (Currently only supported Django's [PostgreSQL backend][postgres-search]). |
| None | `icontains` | Contains search (Default). |
| `&` | `unaccent` | Accent-insensitive search. (Currently only supported Django's [PostgreSQL backend][postgres-lookups]). |

For example:

Expand Down Expand Up @@ -370,3 +371,4 @@ The [djangorestframework-word-filter][django-rest-framework-word-search-filter]
[HStoreField]: https://docs.djangoproject.com/en/3.0/ref/contrib/postgres/fields/#hstorefield
[JSONField]: https://docs.djangoproject.com/en/3.0/ref/contrib/postgres/fields/#jsonfield
[postgres-search]: https://docs.djangoproject.com/en/stable/ref/contrib/postgres/search/
[postgres-lookups]: https://docs.djangoproject.com/en/stable/ref/contrib/postgres/lookups/#unaccent
1 change: 1 addition & 0 deletions rest_framework/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class SearchFilter(BaseFilterBackend):
'=': 'iexact',
'@': 'search',
'$': 'iregex',
'&': 'unaccent',
}
search_title = _('Search')
search_description = _('A search term.')
Expand Down
27 changes: 25 additions & 2 deletions tests/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@

import pytest
from django.core.exceptions import ImproperlyConfigured
from django.db import models
from django.db import connections, models
from django.db.models import CharField, Transform
from django.db.models.functions import Concat, Upper
from django.test import SimpleTestCase, TestCase
from django.test.utils import override_settings

from rest_framework import filters, generics, serializers
from rest_framework.compat import coreschema
from rest_framework.compat import coreschema, postgres_fields
from rest_framework.exceptions import ValidationError
from rest_framework.test import APIRequestFactory

Expand Down Expand Up @@ -146,6 +146,29 @@ class SearchListView(generics.ListAPIView):
{'id': 2, 'title': 'zz', 'text': 'bcd'}
]


@pytest.mark.skipif(not postgres_fields, reason='psycopg2 is not installed')
class SearchPostgreSQLFilterTests(TestCase):
def setUp(self):
connections.databases['default']['ENGINE'] = 'django.db.backends.postgresql'
connections.databases['default']['NAME'] = ':memory:'

def test_unaccent_search(self):
class SearchListView(generics.ListAPIView):
queryset = SearchFilterModel.objects.all()
serializer_class = SearchFilterSerializer
filter_backends = (filters.SearchFilter,)
search_fields = ('title', '&text')

obj = SearchFilterModel(title='Accent títle', text='Accent téxt').save()
view = SearchListView.as_view()
lower_and_unaccent_text = 'accent text'
request = factory.get('/', {'search': lower_and_unaccent_text})
response = view(request)
assert response.data == [
{'id': obj.id, 'title': 'Accent títle', 'text': 'Accent téxt'}
]

def test_regexp_search(self):
class SearchListView(generics.ListAPIView):
queryset = SearchFilterModel.objects.all()
Expand Down

0 comments on commit f8825ba

Please sign in to comment.