-
Notifications
You must be signed in to change notification settings - Fork 771
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Passing the view context to the filterset #857
Comments
My initial thought is that whatever logic you need would be better off in the view, when instantiating the FilterSet. (Either setting attributes or choosing a different FilterSet class or...) Can you provide a concrete use-case? (It's much easier to think about with an actual example.) |
As for
I appreciate this is for advanced usages, but it's always nice to be able to do things when you need them. Currently these cases are only covered by doing hackish and/or painful things (create custom filterset and backend mixins just for it, instantiate with arguments, etc). |
My two cents - coupling the filterset to the view will most likely lead to relatively brittle code. eg, the filterset is now relying on the view's methods and other internals, which are not necessarily well defined. For example, relying on a DRF viewset method would make the filterset incompatible with Django views. At least, it would be necessary to write some amount of compatibility code. Additionally, this would only work with CBVs - not FBVs - and writing unit tests would probably be a pain. It would be necessary to duplicate the initialization performed in In comparison, depending on As to the examples, it would make sense to me that filtering by author and permissions would be performed in the While I strongly recommend against coupling the filterset to the view, the DRF backend could probably provide an easier way to pass custom kwargs to the filterset init. As it currently stands, it's necessary to override the backend on a per-case basis, which is an annoyance to say the least. One possibility - the backend could accept a |
Thanks for the input @rpkilby.
Yes. This is the correct response. (This is exactly where view specific filtering logic is meant to go.) Also, Django Filter's task is to box-up the generic, repeated bits of filtering. Specific view-related logic is out of scope. Do it in the view!
Grrrr.... 🙂 (those watching closely may have noticed) this is the kind of back-injecting API that I don't like. But yes, this would be possible.
|
... Unless you also want the Filterset's filters to behave differently depending on author and permissions.
👍 That's exactly what the DRF Serializers are doing, there should be a Anyway I won't push harder just for the sake of my own usage. As much as I do share your point and also think back-injecting is not nice, I have concrete use cases that are much much tidier and more reusable with such architecture. Having everything in the view, as you suggest, is a also trade-off with keeping filtering logic in filtersets. I guess having access to filterset |
The serializer context is something that's always bothered me, and I'd actually like to see it removed. That said, there isn't really a practical way to do this, given that the hyperlinked relations rely on the context. #865 will actually give you the tools necessary to implement this hook yourself. eg
Something like.. class MyBackend(filters.DjangoFilterBackend):
def get_filterset_kwargs(self, request, queryset, view):
kwargs = super().get_filterset_kwargs(request, queryset, view)
# merge filterset kwargs provided by view class
if hasattr(view, 'get_filterset_kwargs'):
kwargs.update(view.get_filterset_kwargs())
return kwargs
class BooksFilter(filters.FitlerSet):
def __init__(self, *args, author=None, **kwargs):
super().__init__(*args, **kwargs)
# do something w/ author
class BookViewSet(viewsets.ModelViewSet):
filter_backends = [MyBackend]
filter_class = BookFilter
def get_filteset_kwargs(self):
return {
'author': self.get_author(),
} |
If someone like me didn't immediately notice the error in the name of the class view function. It should be |
It would be nice to access the view calling the filterset for context purposes.
This would be pretty much the same thing allowed by DRF's
context
. We already have the request but the view would be a nice addition to do context-based filtering.For example this can be used to access the DRF view action (list/retrieve/etc), know the parent when doing nested listing (
api/object/:id/subobjects/
) or access view properties.It's an easy one to do, and can bring a lot. What do you think?
The text was updated successfully, but these errors were encountered: