Opened 4 months ago
Last modified 2 weeks ago
#36468 assigned Bug
Popup stays blank after adding a related object when filter_horizontal is used
Reported by: | Juan Rocha | Owned by: | Mark |
---|---|---|---|
Component: | contrib.admin | Version: | 5.2 |
Severity: | Normal | Keywords: | filter_horizontal; SelectBox; add_to_cache; |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
When using the "Add another" popup for a *ForeignKey field* in the Django admin and the same ModelAdmin has a ManyToManyField with *filter_horizontal*, the popup window does not close properly after adding the related object.
Instead, the popup remains open and white (blank), and the browser console throws the following error:
:8000/static/admin/js/SelectBox.js:60 Uncaught TypeError: Cannot read properties of undefined (reading 'push') at Object.add_to_cache (:8000/static/admin/js/SelectBox.js:60:33) at :8000/static/admin/j…ctLookups.js:115:31 at NodeList.forEach (<anonymous>) at updateRelatedSelectsOptions (:8000/static/admin/j…ctLookups.js:103:24) at dismissAddRelatedObjectPopup (:8000/static/admin/j…ctLookups.js:133:17) at popup_response.js:12:16 add_to_cache @ :8000/static/admin/js/SelectBox.js:60 (anonymous) @ :8000/static/admin/j…bjectLookups.js:115 updateRelatedSelectsOptions @ :8000/static/admin/j…bjectLookups.js:103 dismissAddRelatedObjectPopup @ :8000/static/admin/j…bjectLookups.js:133 (anonymous) @ popup_response.js:12
This seems to be caused by this block in RelatedObjectLookups.js:
// Update SelectBox cache for related fields. if (typeof SelectBox !== "undefined" && SelectBox.cache[currentSelect.id]) { SelectBox.add_to_cache(select.id, option); SelectBox.redisplay(select.id); }
Steps to Reproduce
- Register a ModelAdmin with:
- A ForeignKey field (with an "Add another" popup)
- A ManyToManyField using filter_horizontal
- Click the "Add another" button next to the ForeignKey field
- In the popup, add the new object and submit
- The popup window stays open with a white screen
- Console shows a JavaScript error from SelectBox.js
Regression
This bug was introduced in commit:
https://github.com/django/django/commit/cd0479ff764272add5e0aba2afcf5649a241ca00
Expected Behavior
The popup should close normally and update the original select field with the new object, as it does when filter_horizontal is not present.
Workaround
Commenting out or removing the SelectBox.add_to_cache and SelectBox.redisplay lines in RelatedObjectLookups.js avoids the error and restores expected behavior.
Version
- Django 5.2.X
- Reproducible in the default admin interface
Change History (9)
comment:1 by , 4 months ago
Description: | modified (diff) |
---|
comment:2 by , 4 months ago
Resolution: | → worksforme |
---|---|
Status: | new → closed |
comment:3 by , 4 weeks ago
Hello Natalia und Juan,
I stumbled accross the same problem, but the example Juan suggested did not work for me either.
In my case, the '+' popup needs to be triggered from within an inline form. A minimal example would look like this
Models:
from django.db import models class Book(models.Model): title = models.CharField() class Article(models.Model): title = models.CharField() books = models.ManyToManyField(Book, blank=True) class Author(models.Model): name = models.CharField() class Feature(models.Model): title = models.CharField() author = models.ForeignKey(Author, on_delete=models.CASCADE) article = models.ForeignKey(Article, on_delete=models.CASCADE)
Admin:
from django.contrib import admin from .models import Article, Author, Book, Feature class FeatureInline(admin.TabularInline): model = Feature @admin.register(Article) class ArticleAdmin(admin.ModelAdmin): inlines = [FeatureInline] filter_horizontal = ["books"] @admin.register(Author) class AuthorAdmin(admin.ModelAdmin): pass @admin.register(Book) class BookAdmin(admin.ModelAdmin): pass @admin.register(Feature) class FeatureAdmin(admin.ModelAdmin): pass
Trying to add an author in the feature's inline (in the article's detail view) will produce the bug described by Juan.
A fix would be, to check, if the select input is managed by the SelectBox (~ it has been initialized) in RelatedObjectLookups.js (line 114)
if (window.SelectBox !== undefined && !SelectBox.cache[currentSelect.id] && SelectBox.cache[select.id]) { ... }
comment:4 by , 2 weeks ago
Resolution: | worksforme |
---|---|
Status: | closed → new |
Triage Stage: | Unreviewed → Accepted |
comment:5 by , 2 weeks ago
Owner: | set to |
---|---|
Status: | new → assigned |
comment:6 by , 2 weeks ago
Has patch: | set |
---|
comment:7 by , 2 weeks ago
I've created a test and a fix at https://github.com/maqnius/django/tree/ticket_36468
./runtests.py --selenium=firefox -k test_popup_closes_with_filter_horizontal
comment:8 by , 2 weeks ago
After investigating more, I figured out, that any select other than the triggered one, is affected by this. The inline is not necessary. Two foreign keys to the same model have the same effect.
from django.db import models class Child(models.Model): name = models.CharField() class Parent(models.Model): name = models.CharField() m2m = models.ManyToManyField(Child, blank=True) fk1 = models.ForeignKey(Child, on_delete=models.CASCADE, related_name="+") fk2 = models.ForeignKey(Child, on_delete=models.CASCADE, related_name="+")
I'll have a look, if this has any consequences for the bugfix.
Hello Juan, thank you for your report. I'm not being able to reproduce: I'm using the models from #35331 (
State
andTransition
) and after your step 3, the pop closes just fine.Can you please share a test project or some tests so that we can replicate and validate the issue?