In Django 2.0+, Django loads jquery.js instead of jquery.min.js when settings.DEBUG=True. See django/django@c19b56f which implements Django #28377 (docs).
In debug mode, when AdminDateWidget, the default admin widget for DateField, appears after a dal widget, select2.js can't find jQuery (Media.merge ordering breaks?) and we also get MediaOrderConflictWarning, as mentioned in #788.
As a temporary workaround, I've overridden AdminDateWidget to always load jquery.min.js, even in debug mode. I imagine the fix should go in Select2WidgetMixin, thoughts?
Interesting, is there any reason you're not using django 2.0 builtin autocomplete feature in the admin ?
Otherwise, I thought dal wouldn't load jquery at all, what's the output scripts like ?
dal is supposed to only load a file that should find the jquery instance to use
Do you think a fix is possible on dal's side ?
Interesting, is there any reason you're not using django 2.0 builtin autocomplete feature in the admin ?
I have two use cases, which if I'm understanding correctly, the built-in feature doesn't support:
Otherwise, I thought dal wouldn't load jquery at all, what's the output scripts like ?
Here is jQuery loaded by AdminDateWidget, when dal field appears before DateField:
<script type="text/javascript" src="/static/autocomplete_light/jquery.init.js"></script>
<script type="text/javascript" src="/static/autocomplete_light/autocomplete.init.js"></script>
<script type="text/javascript" src="/static/autocomplete_light/vendor/select2/dist/js/select2.full.js"></script>
<script type="text/javascript" src="/static/autocomplete_light/vendor/select2/dist/js/i18n/en-US.js"></script>
<script type="text/javascript" src="/static/autocomplete_light/select2.js"></script>
HERE <script type="text/javascript" src="/static/admin/js/vendor/jquery/jquery.js"></script>
<script type="text/javascript" src="/static/admin/js/jquery.init.js"></script>
[...]
If I remove jquery.js from AdminDateWidget Media, we get:
HERE <script type="text/javascript" src="/static/admin/js/vendor/jquery/jquery.js"></script>**
<script type="text/javascript" src="/static/autocomplete_light/jquery.init.js"></script>
<script type="text/javascript" src="/static/autocomplete_light/autocomplete.init.js"></script>
<script type="text/javascript" src="/static/autocomplete_light/vendor/select2/dist/js/select2.full.js"></script>
<script type="text/javascript" src="/static/autocomplete_light/vendor/select2/dist/js/i18n/en-US.js"></script>
<script type="text/javascript" src="/static/autocomplete_light/select2.js"></script>
<script type="text/javascript" src="/static/admin/js/jquery.init.js"></script>
So it looks like minification and debug mode is a red herring. The issue is AdminDateWidget adding jquery.js which Media.merge then orders after dal.
Do you think a fix is possible on dal's side ?
Not sure. We want to use Django's copy of jQuery, but get Django to order it first, right?
Hahah, seems like a lot of fun :D
Perhaps we should add an example app with this use case in the test project ?
How do you suggest we fix this ?
To fix this, I loaded the JQuery file two times by creating a new file template/admin/base.html in my django app, with as content:
{% extends "admin/base.html" %}
{% block extrahead %}
<script type="text/javascript" src="/static/admin/js/vendor/jquery/jquery.js"></script>
{% endblock %}
My new file get loaded first and then the rest of the files get loaded.
<script type="text/javascript" src="/static/admin/js/vendor/jquery/jquery.js"></script>
<script type="text/javascript" src="/static/autocomplete_light/jquery.init.js"></script>
script type="text/javascript" src="/static/autocomplete_light/autocomplete.init.js"></script>
<script type="text/javascript" src="/static/autocomplete_light/vendor/select2/dist/js/select2.full.js"></script>
<script type="text/javascript" src="/static/autocomplete_light/select2.js"></script>
<script type="text/javascript" src="/static/admin/js/vendor/jquery/jquery.js"></script>
<script type="text/javascript" src="/static/admin/js/jquery.init.js"></script>
It is quite a dirty solution, with which I am not satisfied but at least it solved my issue for the short term with minimal effort.
Thanks for your feedback! I wonder why I can't reproduce this in the test project, any idea ?
I am not sure but I believe @daradib pinpointed the cause to be with the AdminDateWidget of Django 2.0. I also had the error in an Admin form where a date widget was present.
Affected by this issue also, wrote a ticket in Django Tickets
https://code.djangoproject.com/ticket/29264
Will use @maxcmoi89 solution for now
I have a custom Autocomplete widget in a project that I use in all places in admin, so in my case, I was able to solve the issue with
from dal import autocomplete
class AutocompleteWidget(autocomplete.Select2)
"""Some custom code ..."""
class Media:
"""Add jQuery dependency so autocomplete light's custom js
is always inserted after jQuery
"""
extra = '' if settings.DEBUG else '.min'
js = [
f'admin/js/vendor/jquery/jquery{extra}.js', # new line
# scripts from original app
'autocomplete_light/jquery.init.js',
'autocomplete_light/autocomplete.init.js',
'autocomplete_light/vendor/select2/dist/js/select2.full.js',
'autocomplete_light/select2.js',
'admin/js/jquery.init.js', # new line
]
Thanks for the quick hack @ron8mcr, please make a pull request if it works for you so we can try it in an RC.
Also, anybody to just use the same jquery and select2 paths as the admin, i mean from django/contrib/admin/static/admin rather than from dal's repo itself ? In this case, dal would only rely on the admin's static and we could drop the git submodule which vendorizes select2 ?
This seems to be the last release blocker for 3.3.0 :joy:
See also https://github.com/django/django/pull/9743, where I've tried to fix this by keeping the admin's media separate from the form's when merging them.
Could you please try #1002 see if that works for you ?
Should be fixed in 35b0046 on master
@jpic
Thanks for addressing this!
Most helpful comment
I have a custom Autocomplete widget in a project that I use in all places in admin, so in my case, I was able to solve the issue with