#30153: ModelAdmin with custom widgets, inlines, and filter_horizontal can merge
media in broken order
-------------------------------+------------------------------------
     Reporter:  roybi          |                    Owner:  nobody
         Type:  Bug            |                   Status:  new
    Component:  contrib.admin  |                  Version:  2.1
     Severity:  Normal         |               Resolution:
     Keywords:                 |             Triage Stage:  Accepted
    Has patch:  0              |      Needs documentation:  0
  Needs tests:  0              |  Patch needs improvement:  0
Easy pickings:  0              |                    UI/UX:  0
-------------------------------+------------------------------------

Comment (by Matthias Kestenholz):

 Hey, yes that might be the right thing to do but maybe there is a solution
 which requires less effort. I suspect that the problem is an inconsistency
 in the way Django collects media from different places. I inserted a few
 print() statements here
 
https://github.com/django/django/blob/893b80d95dd76642e478893ba6d4f46bb31388f1/django/contrib/admin/options.py#L1595

 (Sorry for the big blob in advance)

 {{{
 self.media
  <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>
 <script type="text/javascript" src="/static/admin/js/core.js"></script>
 <script type="text/javascript"
 src="/static/admin/js/admin/RelatedObjectLookups.js"></script>
 <script type="text/javascript" src="/static/admin/js/actions.js"></script>
 <script type="text/javascript" src="/static/admin/js/urlify.js"></script>
 <script type="text/javascript"
 src="/static/admin/js/prepopulate.js"></script>
 <script type="text/javascript"
 src="/static/admin/js/vendor/xregexp/xregexp.js"></script>
 <script type="text/javascript"
 src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"; async="async"
 crossorigin="anonymous"
 
integrity="sha384-kW+oWsYx3YpxvjtZjFXqazFpA7UP/MbiY4jvs+RWZo2+N94PFZ36T6TFkc9O3qoB"></script>
 <script type="text/javascript"
 src="/static/app/plugin_buttons.js"></script>

 adminForm.media
  <link href="/static/imagefield/ppoi.css" type="text/css" media="screen"
 rel="stylesheet">
 <script type="text/javascript" src="/static/imagefield/ppoi.js"></script>
 <script type="text/javascript" src="/static/ckeditor/ckeditor-init.js"
 data-ckeditor-basepath="/static/ckeditor/ckeditor/" id="ckeditor-init-
 script"></script>
 <script type="text/javascript"
 src="/static/ckeditor/ckeditor/ckeditor.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>
 <script type="text/javascript"
 src="/static/admin/js/calendar.js"></script>
 <script type="text/javascript"
 src="/static/admin/js/admin/DateTimeShortcuts.js"></script>

 inline_formset.media <class 'app.articles.models.RichText'>
  <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>
 <script type="text/javascript" src="/static/admin/js/inlines.js"></script>
 <script type="text/javascript"
 src="/static/feincms3/plugin_ckeditor.js"></script>
 <script type="text/javascript" src="/static/ckeditor/ckeditor-init.js"
 data-ckeditor-basepath="/static/ckeditor/ckeditor/" id="ckeditor-init-
 script"></script>
 <script type="text/javascript"
 src="/static/ckeditor/ckeditor/ckeditor.js"></script>

 inline_formset.media <class 'app.articles.models.Image'>
  <link href="/static/imagefield/ppoi.css" type="text/css" media="screen"
 rel="stylesheet">
 <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>
 <script type="text/javascript" src="/static/admin/js/inlines.js"></script>
 <script type="text/javascript" src="/static/imagefield/ppoi.js"></script>
 }}}

 So somehow the widget media files (imagefield and ckeditor) come **after**
 the files added by Django's inlines in inline formsets but **before** them
 in the `helpers.AdminForm` belonging to the `ArticleAdmin` class.

 The problem manifests itself when having any third-party widget (which
 does not reference Django's jquery asset) **before** any Django date
 field, prepopulated field or `filter_*` field in the `fieldsets`
 structure. Reordering fieldsets (or fields) avoids the problem completely.
 Now I still don't understand why the exact same project would work on the
 server and not locally.

 The problem can be worked around by including
 "admin/js/vendor/jquery/jquery%s.js", "admin/js/jquery.init.js" in third-
 party widgets' `Media` definitions. This sucks big time though, especially
 since those widgets don't even require jQuery to work.

 jQuery is included on all modeladmin pages anyway, so a good fix might be
 to remove the jquery and jquery.init.js entries from admin widgets `Media`
 definitions (which makes them incomplete when used outside of Django's
 admin panel, but that's probably not the intention anyway) or make the
 `Media` merging algorithm aware of libraries which are supposed to always
 come first.

 Just for reference, here's the form class and its fields. Putting e.g.
 `publication_date` before `image` makes everything work fine.

 {{{
 form.media
 <link href="/static/imagefield/ppoi.css" type="text/css" media="screen"
 rel="stylesheet">
 <script type="text/javascript" src="/static/imagefield/ppoi.js"></script>
 <script type="text/javascript" src="/static/ckeditor/ckeditor-init.js"
 data-ckeditor-basepath="/static/ckeditor/ckeditor/" id="ckeditor-init-
 script"></script>
 <script type="text/javascript"
 src="/static/ckeditor/ckeditor/ckeditor.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>
 <script type="text/javascript"
 src="/static/admin/js/calendar.js"></script>
 <script type="text/javascript"
 src="/static/admin/js/admin/DateTimeShortcuts.js"></script>

 form.fields
 is_active: <class 'django.forms.fields.BooleanField'>
 title: <class 'django.forms.fields.CharField'>
 excerpt: <class 'django.forms.fields.CharField'>
 image: <class 'django.forms.fields.ImageField'>
 image_ppoi: <class 'django.forms.fields.CharField'>
 meta_title: <class 'django.forms.fields.CharField'>
 meta_description: <class 'django.forms.fields.CharField'>
 meta_image: <class 'django.forms.fields.ImageField'>
 meta_canonical: <class 'django.forms.fields.URLField'>
 meta_author: <class 'django.forms.fields.CharField'>
 meta_robots: <class 'django.forms.fields.CharField'>
 show_teaser_need: <class 'django.forms.fields.BooleanField'>
 show_teaser_competency: <class 'django.forms.fields.BooleanField'>
 teaser_title: <class 'django.forms.fields.CharField'>
 teaser_text_need: <class 'ckeditor.fields.RichTextFormField'>
 teaser_text_competency: <class 'ckeditor.fields.RichTextFormField'>
 teaser_image: <class 'django.forms.fields.ImageField'>
 teaser_image_ppoi: <class 'django.forms.fields.CharField'>
 slug: <class 'django.forms.fields.SlugField'>
 publication_date: <class 'django.forms.fields.SplitDateTimeField'>
 is_featured: <class 'django.forms.fields.BooleanField'>
 author: <class 'django.forms.models.ModelChoiceField'>
 categories: <class 'django.forms.models.ModelMultipleChoiceField'>
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/30153#comment:7>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/065.923d2617bf01d1b93752bc92a35f86d2%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to