diff --git a/tests/test_views.py b/tests/test_views.py index 85d7a30..e450937 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -93,14 +93,14 @@ def test_profile_list_or_filter(client, db, profile_factory, tag_factory): def test_profile_list_negated_filter(client, db, profile, user): - response = client.get(f"/profiles/?name!={user.first_name} {user.last_name}") + response = client.get(f"/profiles/?firstName!={user.first_name}") result = response.json() assert response.status_code == 200, result assert len(result["profiles"]) == 0 def test_profile_list_negated__icontains__filter(client, db, profile, user): - response = client.get(f"/profiles/?name__icontains!={user.first_name}") + response = client.get(f"/profiles/?firstName__icontains!={user.first_name}") result = response.json() assert response.status_code == 200, result assert len(result["profiles"]) == 0 diff --git a/tests/views.py b/tests/views.py index ab261af..34ebe9b 100644 --- a/tests/views.py +++ b/tests/views.py @@ -13,7 +13,9 @@ class ProfileList(CreateAPI, ListAPI): model = Profile queryset = Profile.objects.annotate( - name=Concat("user__first_name", Value(" "), "user__last_name"), + first_name=F("user__first_name"), + last_name=F("user__last_name"), + name=Concat("first_name", Value(" "), "last_name"), date_joined=F("user__date_joined"), ) ordering = ["pk"] @@ -21,6 +23,9 @@ class ProfileList(CreateAPI, ListAPI): permissions = [PublicEndpoint] search_fields = [] filter_fields = [ + "first_name", + "first_name__icontains", + "last_name", "name", "name__icontains", "name__in", diff --git a/worf/views/base.py b/worf/views/base.py index 46b187b..7fdc3fb 100644 --- a/worf/views/base.py +++ b/worf/views/base.py @@ -192,7 +192,7 @@ def get_parts(self, request): return request.parse_file_upload(request.META, BytesIO(request.body)) - def set_bundle(self, raw_bundle): + def set_bundle(self, raw_bundle, allow_negations=False): self.bundle = {} self.keymap = {} @@ -200,7 +200,11 @@ def set_bundle(self, raw_bundle): return for key in raw_bundle.keys(): - field = camel_to_snake(key) + field = ( + camel_to_snake(key[:-1]) + "!" + if allow_negations and key.endswith("!") + else camel_to_snake(key) + ) self.bundle[field] = raw_bundle[key] self.keymap[field] = key @@ -221,7 +225,7 @@ def set_bundle_from_query_string(self, request): for key, value in raw_bundle.items() } - self.set_bundle(coerced_bundle) + self.set_bundle(coerced_bundle, allow_negations=True) def set_bundle_from_request_body(self, request): raw_bundle = {} diff --git a/worf/views/list.py b/worf/views/list.py index 1b74c91..d428999 100644 --- a/worf/views/list.py +++ b/worf/views/list.py @@ -104,16 +104,16 @@ def set_search_lookup_kwargs(self): return for key in self.bundle.keys(): - strip_key = key.rstrip("!") + filter_key = key[:-1] if key.endswith("!") else key - if strip_key not in self.filter_fields: + if filter_key not in self.filter_fields: continue value = self.bundle[key] # support passing `in` and `range` as lists if isinstance(value, list): - if strip_key.endswith("__in") or strip_key.endswith("__range"): + if filter_key.endswith("__in") or filter_key.endswith("__range"): value = ",".join(str(item) for item in value) self.lookup_kwargs[key] = value