#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)
Change History (3)
by , 2 years ago
Attachment: | raw_fk_widget_missing_class.patch added |
---|
follow-up: 2 comment:1 by , 2 years ago
Has patch: | unset |
---|---|
Resolution: | → wontfix |
Status: | new → closed |
Type: | Bug → New feature |
comment:2 by , 2 years 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>', )
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 indjango.contrib.admin.widgets
), any change to this logic would be backward incompatible.