Skip to content

Fix SearchFilter crash when search_fields uses the pk alias - #10071

Merged
auvipy merged 1 commit into
encode:mainfrom
mohamed-alired:fix-searchfilter-pk-distinct
Oct 8, 2026
Merged

auvipy merged 1 commit into
encode:mainfrom
mohamed-alired:fix-searchfilter-pk-distinct

Conversation

@mohamed-alired

Copy link
Copy Markdown
Contributor

Description

SearchFilter.construct_search() resolves the pk alias to the model's primary key
field, so search_fields = ['pk'] (or '=pk', or a lookup through a relation such as
'author__pk') builds a valid query. But must_call_distinct(), which runs right after
to decide whether duplicates are possible, passes 'pk' straight to
Options.get_field(), so the request fails with FieldDoesNotExist and a 500:

class UserList(generics.ListAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    filter_backends = [filters.SearchFilter]
    search_fields = ['=pk']

GET /users/?search=1  ->  FieldDoesNotExist: User has no field named 'pk'

This resolves the alias in must_call_distinct() the same way construct_search()
does. Tests cover pk on the model, through a foreign key, through a many-to-many
(where distinct is still required, and a search by pk through a view. All three fail
without the fix.

construct_search() maps 'pk' to the model's primary key field, but
must_call_distinct() passed 'pk' straight to Options.get_field(), so a view
with search_fields = ['pk'] (or a lookup through a relation such as
'author__pk') raised FieldDoesNotExist and returned a 500.

Resolve the alias in must_call_distinct() the same way construct_search()
does.
@auvipy
auvipy self-requested a review October 7, 2026 18:16
@auvipy
auvipy merged commit 6f6f44b into encode:main Oct 8, 2026
8 checks passed
@browniebroke browniebroke changed the title Fix SearchFilter crash when search_fields uses the pk alias Fix SearchFilter crash when search_fields uses the pk alias Oct 8, 2026
HosseinSayyedMousavi pushed a commit to HosseinSayyedMousavi/django-rest-framework that referenced this pull request Oct 8, 2026
…0071)

construct_search() maps 'pk' to the model's primary key field, but
must_call_distinct() passed 'pk' straight to Options.get_field(), so a view
with search_fields = ['pk'] (or a lookup through a relation such as
'author__pk') raised FieldDoesNotExist and returned a 500.

Resolve the alias in must_call_distinct() the same way construct_search()
does.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

3 participants