Opened 5 years ago

Closed 5 years ago

#30026 closed Bug (needsinfo)

Using collapse class in ModelAdmin fieldset while using the same media file in ModelAdmin's and its inline's form causes wrong media ordering

Reported by: Krzysztof Socha Owned by: nobody
Component: contrib.admin Version: 2.1
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Affects Django 2.0 and 2.1. Does not affect master (or at least I couldn't reproduce the problem given steps below, as its collapse.js no longer depends on jQuery).

Steps to reproduce:

  • Create a model admin with an inline
  • Use the same media file in model admin and inline field (to simplify, use the same widget)
  • Set collapse class on a model admin fieldset

Code snippets:

# models.py
from django.db import models


class Parent(models.Model):
    text = models.CharField(max_length=100)


class Child(models.Model):
    parent = models.ForeignKey(Parent, on_delete=models.CASCADE)
    text = models.CharField(max_length=100)
# admin.py
from django import forms
from django.contrib import admin
from django.db import models

from .models import Child, Parent


class TestWidget(forms.TextInput):
    class Media:
        js = ("foo.js",)


class ChildInline(admin.StackedInline):
    model = Child
    formfield_overrides = {models.CharField: {"widget": TestWidget}}


@admin.register(Parent)
class ParentAdmin(admin.ModelAdmin):
    inlines = [ChildInline]
    fieldsets = (
        ("Fieldset", {
            "classes": ("collapse",),
            "fields": ("text",)
        }),
    )
    formfield_overrides = {models.CharField: {"widget": TestWidget}}

Expected result:

  • Following order of JS files:
    <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="/static/admin/js/collapse.js"></script>
    <script type="text/javascript" src="/static/admin/js/inlines.js"></script>
    <script type="text/javascript" src="/static/foo.js"></script>
    
  • Change view scripts work correctly (inlines handling specifically)

Actual result:

  • A warning is emitted:
    .../django/forms/widgets.py:126: MediaOrderConflictWarning: Detected duplicate Media files in an opposite order:
    admin/js/inlines.js
    admin/js/jquery.init.js
      MediaOrderConflictWarning,
    
  • JS error shown in the console:
    inlines.js:20 Uncaught TypeError: Cannot read property 'fn' of undefined
        at inlines.js:20
        at inlines.js:298
    
  • "Add new Child" button doesn't appear
  • admin/js/inlines.js is loaded before admin/js/vendor/jquery/jquery.js
  • Actual order of JS files:
    <script type="text/javascript" src="/static/admin/js/inlines.js"></script>
    <script type="text/javascript" src="/static/foo.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/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="/static/admin/js/collapse.js"></script>
    

Additional notes:

The issue only occurs if Fieldset.media includes files that aren't in InlineModelAdmin.media (which is only the case if modeladmin has a collapsed fieldset and inline isn't collapsed).

Change History (3)

comment:1 by Carlton Gibson, 5 years ago

Hi Krzysztof.

Do you have a fix in mind?

I ask because I'm not sure it qualifies for a backport and if it's already fixed in master it'll be gone for v2.2...

It might be that it's just a wontfix at this point.

in reply to:  1 comment:2 by Krzysztof Socha, 5 years ago

I'm fairly certain the following is too naive to be a proper fix (+ test): https://github.com/django/django/compare/stable/2.1.x...chaosk:bugfix/30026-collapse-inline-media-issue

I don't have any ideas other than that though.

comment:3 by Carlton Gibson, 5 years ago

Resolution: needsinfo
Status: newclosed

Thanks for the test-case. As you said, it doesn't reproduce on master so I'll going to go for needsinfo here: I can't quickly see why the jQuery dependency should really be relevant, so I'd guess we could come up with a similar case that failed on master, but without that it's hard to proceed.

Happy to reopen if someone can recreate the issue against master.

Note: See TracTickets for help on using tickets.
Back to Top