Skip to content

Commit

Permalink
fix invalid lookup params (#87)
Browse files Browse the repository at this point in the history
  • Loading branch information
EricOuma authored May 2, 2024
1 parent 09cedfd commit 58fe85c
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 28 deletions.
45 changes: 20 additions & 25 deletions django_typesense/changelist.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,31 +427,26 @@ def get_queryset(self, request):
if new_qs is not None:
qs = new_qs

lookup_params_keys = remaining_lookup_params.keys()
model_field_names = set((local_field.name for local_field in self.model._meta.local_fields))
for key in lookup_params_keys:
if key not in model_field_names:
# means k only available in typesense
value = remaining_lookup_params.pop(key)
new_lookup_params = self.model.collection_class.get_django_lookup(key, value)
remaining_lookup_params.update(new_lookup_params)

try:
# Finally, we apply the remaining lookup parameters from the query
# string (i.e. those that haven't already been processed by the
# filters).
qs = qs.filter(**remaining_lookup_params)
except (SuspiciousOperation, ImproperlyConfigured):
# Allow certain types of errors to be re-raised as-is so that the
# caller can treat them in a special way.
raise
except Exception as e:
# Every other error is caught with a naked except, because we don't
# have any other way of validating lookup parameters. They might be
# invalid if the keyword arguments are incorrect, or if the values
# are not in the correct type, so we might get FieldError,
# ValueError, ValidationError, or ?.
raise IncorrectLookupParameters(e)
for param, value in remaining_lookup_params.items():
try:
# Finally, we apply the remaining lookup parameters from the query
# string (i.e. those that haven't already been processed by the
# filters).
qs = qs.filter(**{param: value})
except (SuspiciousOperation, ImproperlyConfigured):
# Allow certain types of errors to be re-raised as-is so that the
# caller can treat them in a special way.
raise
except Exception as e:
# Every other error is caught with a naked except, because we don't
# have any other way of validating lookup parameters. They might be
# invalid if the keyword arguments are incorrect, or if the values
# are not in the correct type, so we might get FieldError,
# ValueError, ValidationError, or ?.

# for django-typesense, possibly means k only available in typesense
new_lookup_params = self.model.collection_class.get_django_lookup(param, value, e)
qs = qs.filter(**new_lookup_params)

# Apply search results
qs, search_may_have_duplicates = self.model_admin.get_search_results(
Expand Down
10 changes: 7 additions & 3 deletions django_typesense/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,21 +198,25 @@ def get_field(cls, name) -> TypesenseField:
return fields[name]

@classmethod
def get_django_lookup(cls, field, value) -> dict:
def get_django_lookup(cls, field, value, exception: Exception) -> dict:
"""
Get the lookup that would have been used for this field in django. Expects to find a method on
the collection called `get_FIELD_lookup` otherwise a NotImplementedError is raised
Args:
collection_field_name: the name of the field in the collection
field: the name of the field in the collection
value: the value to look for
exception: the django exception that led us here
Returns:
A dictionary of the fields to the value.
"""

if "get_%s_lookup" % field not in cls.__dict__:
raise NotImplementedError
raise Exception([
exception,
NotImplementedError("get_%s_lookup is not implemented" % field)
])

method = methodcaller("get_%s_lookup" % field, value)
return method(cls)
Expand Down

0 comments on commit 58fe85c

Please sign in to comment.