Opened 5 months ago
Last modified 5 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 , 5 months ago
| Description: | modified (diff) |
|---|
comment:2 by , 5 months ago
| Resolution: | → worksforme |
|---|---|
| Status: | new → closed |
comment:3 by , 7 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 , 6 weeks ago
| Resolution: | worksforme |
|---|---|
| Status: | closed → new |
| Triage Stage: | Unreviewed → Accepted |
comment:5 by , 6 weeks ago
| Owner: | set to |
|---|---|
| Status: | new → assigned |
comment:6 by , 6 weeks ago
| Has patch: | set |
|---|
comment:7 by , 6 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 , 6 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 (
StateandTransition) 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?