theatlantic / django-nested-admin

Django admin classes that allow for nested inlines
http://django-nested-admin.readthedocs.org/
Other
690 stars 97 forks source link

Javascript for autocompletes breaks in Django 5.0 #244

Open lachlancannon opened 5 months ago

lachlancannon commented 5 months ago

I've spent a good while trying to see a good way to fix the order, but was unsuccessful. I hope I'm missing something easy, but it seems like the way nested admin merges its javascript with the django admin javascript is now changing the order of the loaded tags in such a way that it breaks autocomplete fields.

danieltmartin commented 4 months ago

I'm having the same issue. I found that the relevant scripts are being loaded in this order:

jquery.js
jquery.init.js (calls jQuery.noConflict(true), removing jQuery from the global scope)
select2.full.js

whereas before select2.full.js would become between the others.

danieltmartin commented 4 months ago

I believe I found the issue. In compat.py, there is some code that backports the topological sorting of media files from Django 2.x to Django 1.x. This is done when the stable_topological_sort import from Django is not found. However, in Django 5, this function was removed in favor of the graphlib module built into Python since 3.9: https://github.com/django/django/commit/1282b5e4207440af659ef0e0e0c486fdfba8e7b7. This inadvertently triggers the backported topological sort from Django 2.x.

I don't know exactly why the backported version doesn't work properly, but I'm assuming there are fixes in it made since Django 2 that weren't copied to the backported version.

I confirmed that changing this line: https://github.com/theatlantic/django-nested-admin/blob/14d40a18e6b4b119779f17fac429181d8a17cf72/nested_admin/compat.py#L49C30-L49C53

to be skipped on Django 5 resolves the issue:

if (MergeSafeMedia is None or stable_topological_sort is None) and django.VERSION[0] < 5:
ron8mcr commented 4 months ago

@danieltmartin thanks for your investigation. Based on this I've add following monkey-patch that allowed to upgrade project to django 5.0 without maintaining forked version:

"""Monkey-patch for django>5.0 for `nested_admin`.

In Django>=5.0 was removed module `django.utils.topological_sort`
(see https://github.com/django/django/commit/1282b5e4207440af659ef0e0e0c486fdfba8e7b7)
And this module is used by `django-nested-admin` to backport media ordering
for old Django versions:
https://github.com/theatlantic/django-nested-admin/blob/master/nested_admin/compat.py

While proper fix is not added to `django-nested-admin`, this monkey patch may
be used to make `nested-admin` work with Django 5.0.

More info: https://github.com/theatlantic/django-nested-admin/issues/244

"""
import sys
import types

def mock(*args, **kwargs):
    raise NotImplementedError(
        "This is just mock and not actual implementation"
    )

dynamic_module = types.ModuleType("dynamic_topological_sort")
dynamic_module.CyclicDependencyError = mock
dynamic_module.stable_topological_sort = mock

sys.modules.setdefault("django.utils.topological_sort", dynamic_module)

This code can be placed in some of the __init__.py files in the app that imported before the nested_admin.

P.S. I've faced this issue when using django-autocomplete-light. I've seen following error in JS console:

 An instance of jQuery or a jQuery-compatible library was not found. Make sure that you are including jQuery before Select2 on your web page.

(hope this will help to find this issue faster)