Skip to content
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

Adding FlexFieldsFilterBackend immediately breaks the app #46

Open
striveforbest opened this issue Mar 3, 2020 · 3 comments
Open

Adding FlexFieldsFilterBackend immediately breaks the app #46

striveforbest opened this issue Mar 3, 2020 · 3 comments

Comments

@striveforbest
Copy link

striveforbest commented Mar 3, 2020

I am utilizing drf-flex-fields heavily and everything works fine until the moment i add:

REST_FRAMEWORK = {
    ...
    'DEFAULT_FILTER_BACKENDS': (
        'rest_flex_fields.filter_backends.FlexFieldsFilterBackend',
    ),
    ...
}

It crashes the app with the following traceback:

INFO 2020-03-03 21:38:35,864 autoreload 90410 4456287680 Watching for file changes with StatReloader
Performing system checks...

Exception in thread django-main-thread:
Traceback (most recent call last):
  File "/usr/local/Cellar/python@3.8/3.8.1/Frameworks/Python.framework/Versions/3.8/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/usr/local/Cellar/python@3.8/3.8.1/Frameworks/Python.framework/Versions/3.8/lib/python3.8/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/django/utils/autoreload.py", line 53, in wrapper
    fn(*args, **kwargs)
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/django/core/management/commands/runserver.py", line 117, in inner_run
    self.check(display_num_errors=True)
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/django/core/management/base.py", line 392, in check
    all_issues = self._run_checks(
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/django/core/management/base.py", line 382, in _run_checks
    return checks.run_checks(**kwargs)
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/django/core/checks/registry.py", line 72, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/django/core/checks/urls.py", line 13, in check_url_config
    return check_resolver(resolver)
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/django/core/checks/urls.py", line 23, in check_resolver
    return check_method()
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/django/urls/resolvers.py", line 407, in check
    for pattern in self.url_patterns:
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/django/utils/functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/django/urls/resolvers.py", line 588, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/django/utils/functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/django/urls/resolvers.py", line 581, in urlconf_module
    return import_module(self.urlconf_name)
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 783, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/Users/alex.zagoro/projects/gagosian/noya/gagosian/urls.py", line 6, in <module>
    path('api/v1/', include('gagosian.api.v1.urls', namespace='api'))
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/django/urls/conf.py", line 34, in include
    urlconf_module = import_module(urlconf_module)
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 783, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/Users/alex.zagoro/projects/gagosian/noya/gagosian/api/v1/urls.py", line 4, in <module>
    from .contacts import urls as contacts_urls
  File "/Users/alex.zagoro/projects/gagosian/noya/gagosian/api/v1/contacts/urls.py", line 3, in <module>
    from .viewsets import (
  File "/Users/alex.zagoro/projects/gagosian/noya/gagosian/api/v1/contacts/viewsets.py", line 1, in <module>
    from rest_framework.viewsets import ModelViewSet
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/rest_framework/viewsets.py", line 27, in <module>
    from rest_framework import generics, mixins, views
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/rest_framework/generics.py", line 24, in <module>
    class GenericAPIView(views.APIView):
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/rest_framework/generics.py", line 43, in GenericAPIView
    filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/rest_framework/settings.py", line 220, in __getattr__
    val = perform_import(val, attr)
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/rest_framework/settings.py", line 168, in perform_import
    return [import_from_string(item, setting_name) for item in val]
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/rest_framework/settings.py", line 168, in <listcomp>
    return [import_from_string(item, setting_name) for item in val]
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/rest_framework/settings.py", line 177, in import_from_string
    return import_string(val)
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/django/utils/module_loading.py", line 17, in import_string
    module = import_module(module_path)
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/rest_flex_fields/__init__.py", line 3, in <module>
    from .views import FlexFieldsModelViewSet
  File "/Users/alex.zagoro/venv/noya-TS4FQGPC/lib/python3.8/site-packages/rest_flex_fields/views.py", line 21, in <module>
    class FlexFieldsModelViewSet(FlexFieldsMixin, viewsets.ModelViewSet):
AttributeError: partially initialized module 'rest_framework.viewsets' has no attribute 'ModelViewSet' (most likely due to a circular import)

Adding the backend directly to the view works fine.

@bharling
Copy link

bharling commented Apr 2, 2020

Yeah seeing this too, but I get:

ImportError: Could not import 'rest_flex_fields.filter_backends.FlexFieldsFilterBackend' for API setting 'DEFAULT_FILTER_BACKENDS'. ImportError: cannot import name 'GenericViewSet'.

looks like a circular import also

@wolph
Copy link

wolph commented Oct 9, 2020

As a workaround (I also posted this at #59 which appears to be a duplicate) you can set the filter backend at the view:

import rest_flex_fields.filter_backends as flex_filters
from rest_framework import viewsets


class ModelViewSet(viewsets.ModelViewSet):
    filter_backends = viewsets.ModelViewSet.filter_backends + [
        flex_filters.FlexFieldsFilterBackend,
    ]

@pablolmedorado
Copy link
Contributor

pablolmedorado commented Nov 29, 2020

Starting from @wolph idea, I have created a mixin to replace the "FlexFieldsMixin" that includes the FilterBackend and also respects the user's settings.

I'll leave the code here just in case there was anyone interested.

from rest_flex_fields.filter_backends import FlexFieldsFilterBackend
from rest_flex_fields.views import FlexFieldsMixin
from rest_framework.settings import api_settings


class FlexFieldsOptimizedMixin(FlexFieldsMixin):
    filter_backends = [FlexFieldsFilterBackend] + api_settings.DEFAULT_FILTER_BACKENDS
from rest_framework import viewsets
from .mixins import FlexFieldsOptimizedMixin


class ModelViewSet(FlexFieldsOptimizedMixin, viewsets.ModelViewSet):
    ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants