-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
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
DjangoFilterBackend deprecation breaks mro #5089
Comments
Interesting. |
Here is another example that illuminates what is actually happening... class NewDjangoFilterBackend:
def filter_queryset(self):
print("Inside django-filters")
class DefaultDRFBackwardsCompat:
def __new__(*args, **kwargs):
return NewDjangoFilterBackend()
class OurCustomerFilterBackendParent:
def filter_queryset(self):
print("Inside Our Parent Object")
class OurFilterBackend(OurCustomerFilterBackendParent, DefaultDRFBackwardsCompat):
def x(self):
print("in x")
OurFilterBackend().x()
>>> Traceback (most recent call last):
>>> File "<stdin>", line 25, in <module>
>>> AttributeError: 'NewDjangoFilterBackend' object has no attribute 'x' It looks like, because of the way |
@mattjmorrison Can I just check, if you update to use |
Sorry, didn't get to the end:
The issue is here. There's no effort at all to handle a custom backend class. I'm not sure of the cost/benefit of bullet-proofing this at point. Obviously a PR would be worth merging but it's a bit of an edge-case that'll drop out shortly. (It's quite interesting though) |
It should be straightforward to fix this:
|
not going to work as it'll require django_filters to be installed in any case. |
This could work with if django_filters:
DFBase = django_filters.rest_framework.DjangoFilterBackend
else:
DFBase = BaseFilterBackend
class DjangoFilterBackend(DFBase): |
yup could do. |
Closed via #5117. |
Checklist
master
branch of Django REST framework.Steps to reproduce
I ran into a really nasty bug today because of how we are using DjangoFilterBackend. Here is our scenario... we have a FilterBackend as well as a parent filter backend (that is really a mixin). Our backend extends our mixin as well as the rest_framework.filters.DjangoFilterBackend.... so it looks something like this
Expected behavior
(this is in Python 3.4.6 btw)
I expect, because of Python's normal MRO that
filter_queryset
onOurCustomerFilterBackendParent
will be called.Actual behavior
Due to the
__new__
inDefaultDRFBackwardsCompat
thefilter_queryset
inside ofdjango-filters
is called instead.It is not very clear to my why this would happen... but there has to be a way to deprecate a class without breaking Python's MRO.
In our case, the fix to our bug was to just use the DjangoFilterBackend from django-filters instead of the one in rest_framework... but this just seems like a potentially dangerous way to make something be backwards compatible.
The text was updated successfully, but these errors were encountered: