mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-18 04:02:35 +03:00
Allow search to split also by comma after smart split
This commit is contained in:
parent
82c42dc5db
commit
1ce85d01b5
|
@ -20,6 +20,21 @@ from rest_framework.fields import CharField
|
|||
from rest_framework.settings import api_settings
|
||||
|
||||
|
||||
def search_smart_split(search_terms):
|
||||
"""generator that first splits string by spaces, leaving quoted phrases togheter,
|
||||
then it splits non-quoted phrases by commas.
|
||||
"""
|
||||
for term in smart_split(search_terms):
|
||||
# trim commas to avoid bad matching for quoted phrases
|
||||
term = term.strip(',')
|
||||
if term.startswith(('"', "'")) and term[0] == term[-1]:
|
||||
# quoted phrases are kept togheter without any other split
|
||||
yield unescape_string_literal(term)
|
||||
else:
|
||||
# non-quoted tokens are split by comma, keeping only non-empty ones
|
||||
yield from (sub_term.strip() for sub_term in term.split(',') if sub_term)
|
||||
|
||||
|
||||
class BaseFilterBackend:
|
||||
"""
|
||||
A base class from which all filter backend classes should inherit.
|
||||
|
@ -144,9 +159,7 @@ class SearchFilter(BaseFilterBackend):
|
|||
|
||||
base = queryset
|
||||
conditions = []
|
||||
for term in smart_split(search_terms):
|
||||
if term.startswith(('"', "'")) and term[0] == term[-1]:
|
||||
term = unescape_string_literal(term)
|
||||
for term in search_smart_split(search_terms):
|
||||
queries = [
|
||||
models.Q(**{orm_lookup: term})
|
||||
for orm_lookup in orm_lookups
|
||||
|
|
|
@ -6,7 +6,7 @@ from django.core.exceptions import ImproperlyConfigured
|
|||
from django.db import models
|
||||
from django.db.models import CharField, Transform
|
||||
from django.db.models.functions import Concat, Upper
|
||||
from django.test import TestCase
|
||||
from django.test import SimpleTestCase, TestCase
|
||||
from django.test.utils import override_settings
|
||||
|
||||
from rest_framework import filters, generics, serializers
|
||||
|
@ -17,6 +17,25 @@ from rest_framework.test import APIRequestFactory
|
|||
factory = APIRequestFactory()
|
||||
|
||||
|
||||
class SearchSplitTests(SimpleTestCase):
|
||||
|
||||
def test_keep_quoted_togheter_regardless_of_commas(self):
|
||||
assert ['hello, world'] == list(filters.search_smart_split('"hello, world"'))
|
||||
|
||||
def test_strips_commas_around_quoted(self):
|
||||
assert ['hello, world'] == list(filters.search_smart_split(',,"hello, world"'))
|
||||
assert ['hello, world'] == list(filters.search_smart_split(',,"hello, world",,'))
|
||||
assert ['hello, world'] == list(filters.search_smart_split('"hello, world",,'))
|
||||
|
||||
def test_splits_by_comma(self):
|
||||
assert ['hello', 'world'] == list(filters.search_smart_split(',,hello, world'))
|
||||
assert ['hello', 'world'] == list(filters.search_smart_split(',,hello, world,,'))
|
||||
assert ['hello', 'world'] == list(filters.search_smart_split('hello, world,,'))
|
||||
|
||||
def test_splits_quotes_followed_by_comma_and_sentence(self):
|
||||
assert ['"hello', 'world"', 'found'] == list(filters.search_smart_split('"hello, world",found'))
|
||||
|
||||
|
||||
class BaseFilterTests(TestCase):
|
||||
def setUp(self):
|
||||
self.original_coreapi = filters.coreapi
|
||||
|
@ -435,7 +454,7 @@ class SearchFilterToManyTests(TestCase):
|
|||
search_fields = ('=name', 'entry__headline', '=entry__pub_date__year')
|
||||
|
||||
view = SearchListView.as_view()
|
||||
request = factory.get('/', {'search': 'Lennon 1979'})
|
||||
request = factory.get('/', {'search': 'Lennon,1979'})
|
||||
response = view(request)
|
||||
assert len(response.data) == 1
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user