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

Code changes needed to update to django-rest-framework latest version #5517

Closed
glennmatthews opened this issue Apr 1, 2024 · 0 comments · Fixed by #5546
Closed

Code changes needed to update to django-rest-framework latest version #5517

glennmatthews opened this issue Apr 1, 2024 · 0 comments · Fixed by #5546
Assignees
Labels
dependencies Pull requests that update a dependency file type: bug Something isn't working as expected

Comments

@glennmatthews
Copy link
Contributor

Environment

  • Nautobot version (Docker tag too if applicable): 2.2.0

Steps to Reproduce

  1. poetry add django-rest-framework~3.15.0
  2. Build docker container
  3. Start Nautobot

Expected Behavior

Nautobot to start successfully

Observed Behavior

Traceback (most recent call last):
  File "/usr/local/bin/nautobot-server", line 6, in <module>
    sys.exit(main())
  File "/source/nautobot/core/cli/__init__.py", line 286, in main
    execute_from_command_line([sys.argv[0], *unparsed_args])
  File "/usr/local/lib/python3.8/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.8/site-packages/django/core/management/__init__.py", line 395, in execute
    django.setup()
  File "/usr/local/lib/python3.8/site-packages/django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/usr/local/lib/python3.8/site-packages/django/apps/registry.py", line 122, in populate
    app_config.ready()
  File "/source/nautobot/circuits/apps.py", line 14, in ready
    super().ready()
  File "/source/nautobot/core/apps/__init__.py", line 57, in ready
    register_menu_items(menu_items)
  File "/source/nautobot/core/apps/__init__.py", line 174, in register_menu_items
    item.link = reverse(item.link, args=item.args, kwargs=item.kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/urls/base.py", line 54, in reverse
    app_list = resolver.app_dict[ns]
  File "/usr/local/lib/python3.8/site-packages/django/urls/resolvers.py", line 530, in app_dict
    self._populate()
  File "/usr/local/lib/python3.8/site-packages/django/urls/resolvers.py", line 464, in _populate
    for url_pattern in reversed(self.url_patterns):
  File "/usr/local/lib/python3.8/site-packages/django/utils/functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/usr/local/lib/python3.8/site-packages/django/urls/resolvers.py", line 602, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/usr/local/lib/python3.8/site-packages/django/utils/functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/usr/local/lib/python3.8/site-packages/django/urls/resolvers.py", line 595, in urlconf_module
    return import_module(self.urlconf_name)
  File "/usr/local/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 843, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/source/nautobot/core/urls.py", line 42, in <module>
    path("api/", include("nautobot.core.api.urls")),
  File "/usr/local/lib/python3.8/site-packages/django/urls/conf.py", line 34, in include
    urlconf_module = import_module(urlconf_module)
  File "/usr/local/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 843, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/source/nautobot/core/api/urls.py", line 49, in <module>
    path("extras/", include("nautobot.extras.api.urls")),
  File "/usr/local/lib/python3.8/site-packages/django/urls/conf.py", line 34, in include
    urlconf_module = import_module(urlconf_module)
  File "/usr/local/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 843, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/source/nautobot/extras/api/urls.py", line 54, in <module>
    router.register("jobs", views.JobByNameViewSet)
  File "/usr/local/lib/python3.8/site-packages/rest_framework/routers.py", line 59, in register
    raise ImproperlyConfigured(msg)
django.core.exceptions.ImproperlyConfigured: Router with basename "job" is already registered. Please provide a unique basename for viewset "<class 'nautobot.extras.api.views.JobByNameViewSet'>"

This appears to due to https://github.com/nautobot/nautobot/blob/develop/nautobot/extras/api/urls.py#L53-L54, where we're registering two different viewsets under the /api/extras/jobs/ URL endpoint. This was permitted and valid in DRF 3.14 and earlier; it appears that this new restriction was added in 3.15 by encode/django-rest-framework#8438.

Note that providing a unique basename for one of these viewsets would be a breaking change for us, as it would change the reversible URL names for the updated viewset. Most likely, to preserve the existing URL names, we'll have to figure out a way to merge the two viewset classes into a single combined viewset class; an alternate possibility might be to override the BaseRouter.is_already_registered() function to bypass this check and restore the prior functionality?

@glennmatthews glennmatthews added type: bug Something isn't working as expected dependencies Pull requests that update a dependency file labels Apr 1, 2024
@glennmatthews glennmatthews self-assigned this Apr 9, 2024
@glennmatthews glennmatthews mentioned this issue Apr 9, 2024
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dependencies Pull requests that update a dependency file type: bug Something isn't working as expected
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant