Opened 23 months ago

Closed 23 months ago

Last modified 23 months ago

#34257 closed New feature (wontfix)

ForeignKeyRawIdWidget doesn't include vForeignKeyRawIdAdminField class when custom class passed in attrs

Reported by: Kevin Marsh Owned by: nobody
Component: contrib.admin Version: dev
Severity: Normal Keywords: widget, admin, raw_id_fields
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I had a situation where I wanted to add an extra class to the ForeignKeyRawIdWidget widget. I noticed that doing something like:

attrs = {"class": "myAdditionalClass"}
widget = ForeignKeyRawIdWidget(rel, admin_site, attrs=attrs)

resulted in the widget not having the required vForeignKeyRawIdAdminField class since under the hood ForeignKeyRawIdWidget.get_context does something like:

context["widget"]["attrs"].setdefault("class", "vForeignKeyRawIdAdminField")

meaning the rendered <input /> looks like:

<input class="myAdditionalClass" ...

instead of:

<input class="myAdditionalClass vForeignKeyRawIdAdminField" ...

Note that this same issue applies to the ManyToManyRawIdWidget and corresponding vManyToManyRawIdAdminField class.


I'm not sure if ForeignKeyRawIdWidget/ManyToManyRawIdWidget is meant to be public, but it'd be nice if we could resolve this in the source. Currently I can work around this by simply doing:

attrs = {"class": "myAdditionalClass vForeignKeyRawIdAdminField"}
widget = ForeignKeyRawIdWidget(rel, admin_site, attrs=attrs)

I can create a PR based on a similar solution in the patch (and also fix ManyToManyRawIdWidget) if this gets accepted.

Attachments (1)

raw_fk_widget_missing_class.patch (1.7 KB ) - added by Kevin Marsh 23 months ago.

Download all attachments as: .zip

Change History (3)

by Kevin Marsh, 23 months ago

comment:1 by Mariusz Felisiak, 23 months ago

Has patch: unset
Resolution: wontfix
Status: newclosed
Type: BugNew feature

I don't see any issue here, TBH. As far as I'm aware, attributes passed in attrs override default values for all widgets (not only widgets defined in django.contrib.admin.widgets), any change to this logic would be backward incompatible.

in reply to:  1 comment:2 by Kevin Marsh, 23 months ago

Replying to Mariusz Felisiak:

Thanks Mariusz, hopefully at least this ticket will serve as instructions for others about how to ensure the JS in the widget still works when adding additional classes (although is at risk of breaking if vForeignKeyRawIdAdminField is ever renamed in a new version of Django).

As far as I'm aware, attributes passed in attrs override default values for all widgets

Not sure that's entirely true, eg. I think something like FilteredSelectMultiple just ignores any "class" attr:

class FilteredSelectMultipleWidgetTest(SimpleTestCase):
    #... rest of existing test class
    def test_render_ignores_additional_attrs(self):
        # This widget ignores any class override in `attrs`
        w = widgets.FilteredSelectMultiple("test", False, attrs={"class": "myAdditionalClass"})
        self.assertHTMLEqual(
            w.render("test", "test"),
            '<select multiple name="test" class="selectfilter" '
            'data-field-name="test" data-is-stacked="0">\n</select>',
        )
Note: See TracTickets for help on using tickets.
Back to Top