def test_query_parser_default_search_too_short(self): # if the search query without a field is less than a specified # length of characters (currently 3), then it should # throw `SearchQueryTooShortException()` from `query_parser.py` default_field_lookups = ['field_a__icontains', 'field_b'] query_string = 'fo' with self.assertRaises(SearchQueryTooShortException) as e: parse(query_string, default_field_lookups) assert 'Your query is too short' in str(e.exception)
def filter_queryset(self, request, queryset, view): try: q = request.query_params['q'] except KeyError: return queryset try: q_obj = parse( q, default_field_lookups=view.search_default_field_lookups ) except ParseError: return queryset.model.objects.none() except SearchQueryTooShortException as e: # raising an exception if the default search query without a # specified field is less than a set length of characters - # currently 3 raise e try: # If no search field is specified, the search term is compared # to several default fields and therefore may return a copies # of the same match, therefore the `distinct()` method is required return queryset.filter(q_obj).distinct() except (FieldError, ValueError): return queryset.model.objects.none()
def test_query_parser(self): query_string = ''' (a:a OR b:b AND c:c) AND d:d OR ( snakes:🐍🐍 AND NOT alphabet:🍲soup ) NOT 'in a house' NOT "with a mouse" ''' expected_q = ((Q(a='a') | Q(b='b') & Q(c='c')) & Q(d='d') | (Q(snakes='🐍🐍') & ~Q(alphabet='🍲soup')) & ~Q(summary__icontains='in a house') & ~Q(summary__icontains='with a mouse')) self.assertEqual(repr(expected_q), repr(parse(query_string)))
def filter_queryset(self, request, queryset, view): try: q = request.query_params['q'] except KeyError: return queryset try: q_obj = parse(q) except ParseError: return queryset.model.objects.none() try: return queryset.filter(q_obj) except (FieldError, ValueError): return queryset.model.objects.none()
def test_query_parser(self): query_string = ''' (a:a OR b:b AND c:c) AND d:d OR ( snakes:🐍🐍 AND NOT alphabet:🍲soup ) NOT 'in a house' NOT "with a mouse" ''' default_field_lookups = ['field_a__icontains', 'field_b'] expected_q = ( (Q(a='a') | Q(b='b') & Q(c='c')) & Q(d='d') | (Q(snakes='🐍🐍') & ~Q(alphabet='🍲soup')) & ~(Q(field_a__icontains='in a house') | Q(field_b='in a house')) & ~(Q(field_a__icontains='with a mouse') | Q(field_b='with a mouse'))) assert expected_q == parse(query_string, default_field_lookups)
def __get_parsed_parameters(self, request: Request) -> dict: """ Returns the results of `get_parsed_parameters` utility. Useful in this class to detect specific parameters and to return according queryset """ try: q = request.query_params['q'] except KeyError: return {} try: q_obj = parse( q, default_field_lookups=ASSET_SEARCH_DEFAULT_FIELD_LOOKUPS) except (ParseError, SearchQueryTooShortException): # Let's `SearchFilter` handle errors return {} else: return get_parsed_parameters(q_obj)
def test_query_parser_no_specified_field(self): query_string = 'foo' default_field_lookups = ['field_a__icontains', 'field_b'] expected_q = (Q(field_a__icontains='foo') | Q(field_b='foo')) assert repr(expected_q) == repr( parse(query_string, default_field_lookups))