Closed Farhaduneci closed 1 year ago
@Farhaduneci hello :wave:
I'm not sure I'm picking the right context of the question, so if the provided answer is not what you are looking for, just provide more details + an example :pray:
Otherwise, when dealing with query params, we usually pass them thru a serializer (we call this FilterSerializer
) and then pass the validated_data
to the respective service or selector.
After this, how you handle filtration, is up to you. Usually https://django-filter.readthedocs.io/en/stable/ is more than enough.
Here is an example of a simple list API with filters from GET params - https://github.com/HackSoftware/Django-Styleguide-Example/blob/master/styleguide_example/users/apis.py#L13
Cheers!
I appreciate your near-immidate response. The repository feels so alive and under active maintenance 🔥
What you've stated isn't what I meant, unfortunately. I've seen your implementation of filters in the example project (which is a reversed-engineered version of the way that DRF handles this as you've stated in the docs).
My question is about the search functionality insted. Have a look at this View for example:
...
from rest_framework.filters import OrderingFilter, SearchFilter
class GiftAdminList(ListAPIView):
serializer_class = GiftAdminListSerializer
permission_classes = (FullDjangoModelPermissions,)
filter_backends = [DjangoFilterBackend, OrderingFilter, SearchFilter]
filterset_fields = ["type"]
ordering_fields = ["created_at"]
search_fields = ["invoice__id", "user__email", "user__mobile"]
swagger_tags = ["Gift"]
def get_queryset(self):
return Gift.objects.all()
Your example shows how we can, and you've handled the functionality of DjangoFilterBackend and OrderingFilter in this code.
What about the SearchFilter?
What is the best way to reverse-engineer this part?
@RadoRado I mention you here in case that you've missed this one!
@Farhaduneci Okay, if I understand you correctly, the question is - "How do we replicate this behavior in a selector?"
How I usually approach this is by examining what's the actual behavior of rest_framework.filters.SearchFilter
:
The main thing it does is something called `filter_queryset:
from rest_framework.filters import SearchFilter
filter = SearchFilter()
qs = ...
qs = filter.filter_queryset(request, qs, view)
It gets the values from the params from request
, and view
is required because of the search_fields
attribute.
This means we can simply create mock objects to pass to the search filter & construct a selector like that:
from types import SimpleNamespace as Object
from rest_framework.filters import SearchFilter
def some_selector(*, x, y, z, query_params):
qs = SomeModel.objects.all()
request = Object(query_params=query_params)
view = Object(search_fields=your_search_fields)
search_filter = SearchFilter()
qs = search_filter.filter_queryset(request, qs, view)
....
And you are good to go :+1:
Of course, you can simply pass the request & view to the selector, if you feel like it.
Here's the implementation of SearchFilter
for reference - https://github.com/encode/django-rest-framework/blob/master/rest_framework/filters.py#L39
Yes, that's the question I meant to ask. Your example is exactly what I was looking for. Thank you so much!
Hey there, thanks for your great effort. I wonder how would you handle a search query parameter which acts like
SearchFilter
inside a normal generic view?