#34025 closed Bug (fixed)
Autocomplete field fills all empty required fields references to the same model when added a choice in popup.
Reported by: | Alexandre da Silva | Owned by: | David Sanders |
---|---|---|---|
Component: | contrib.admin | Version: | 4.1 |
Severity: | Release blocker | Keywords: | admin, autocomplete |
Cc: | Marcelo Galigniana | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | yes |
Description (last modified by )
Example of how to reproduce:
- create a model Person.
- create a model Order with 2 fks pointing to person, for example: supplier and customer
from django.db import models # Create your models here. class Person(models.Model): name = models.CharField(max_length=255) def __str__(self): return self.name class Order(models.Model): supplier = models.ForeignKey(Person, related_name='the_supplier', on_delete=models.PROTECT) customer = models.ForeignKey(Person, related_name='the_customer', on_delete=models.PROTECT)
- create an admin page for Order.
- place the two fields in autocomplete_fields:
from django.contrib import admin from sales.models import * class PersonAdmin(admin.ModelAdmin): search_fields = ['name'] class OrderAdmin(admin.ModelAdmin): autocomplete_fields = ['supplier', 'customer'] admin.site.register(Person, PersonAdmin) admin.site.register(Order, OrderAdmin)
- do the migration stuff and run the app.
when create an supplier from + symbol near the supplier, when close the window both fields get updated with the ID
this also occurs when editing.
ps. I´m not an expert but the code that seems to introduce this bug is on commit c72f6f36c13a21f6db3d4f85d2d3cec87bad45e6
probably on data-model-ref tag, since in the page all autocompletes have the same data-model-ref value, in this example will be "person"
function updateRelatedSelectsOptions(currentSelect, win, objId, newRepr, newId) { // After create/edit a model from the options next to the current // select (+ or :pencil:) update ForeignKey PK of the rest of selects // in the page. const path = win.location.pathname; // Extract the model from the popup url '.../<model>/add/' or // '.../<model>/<id>/change/' depending the action (add or change). const modelName = path.split('/')[path.split('/').length - (objId ? 4 : 3)]; const selectsRelated = document.querySelectorAll(`[data-model-ref="${modelName}"] select`); selectsRelated.forEach(function(select) { if (currentSelect === select) { return; } let option = select.querySelector(`option[value="${objId}"]`); if (!option) { option = new Option(newRepr, newId); select.options.add(option); return; } option.textContent = newRepr; option.value = newId; }); }
Change History (14)
comment:1 by , 2 years ago
Description: | modified (diff) |
---|
comment:2 by , 2 years ago
Component: | Uncategorized → contrib.admin |
---|
comment:3 by , 2 years ago
After a bit of playing around with jQuery select2 I believe this is actually fixable - because select2 allows required selects to be deselectable.
Before the option is added, we can observe the value of the select is null
for selects that haven't an option selected yet. After adding the option, if the previously observed value was null
then we can "deselect" it again.
comment:5 by , 2 years ago
Has patch: | set |
---|
comment:6 by , 2 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:7 by , 2 years ago
While I could reproduce the described issue for creates, I couldn't do so for edits. In the edit screen only the field for which I clicked "+" was updated.
To reproduce on edit, the steps are:
- create a new record for order
- select an existing supplier on select combobox, then click on edit.
- save the supplier record, customer select also gets updated
Applied patch and tested locally, so the issue semms to be resolved for both cases, add and edit.
comment:8 by , 2 years ago
Alexandre the PR I've submitted above looks like it fixes the issues you've described. Are you able to try it out and report back if it works?
If it does work for you then this will increase the chance of the ticket & patch being accepted.
comment:10 by , 2 years ago
Thanks Alexandre, will wait for a member of the triage team… Djangocon is on atm so we may need to be patient :)
comment:11 by , 2 years ago
Cc: | added |
---|---|
Needs documentation: | set |
Needs tests: | set |
Severity: | Normal → Release blocker |
Summary: | Bug on autocomplete field when two fields from same reference model are added in same page → Autocomplete field fills all empty required fields references to the same model when added a choice in popup. |
Triage Stage: | Unreviewed → Accepted |
Thanks for the report!
Regression in c72f6f36c13a21f6db3d4f85d2d3cec87bad45e6.
comment:12 by , 2 years ago
Needs documentation: | unset |
---|---|
Needs tests: | unset |
Triage Stage: | Accepted → Ready for checkin |
A couple of points here:
(note: I only tested on Chrome, behaviour could differ for other browsers)
null=True, blank=True
then this behaviour isn't shown. I'm not sure this is something that's fixable as this is the behaviour shown for native selects. If you create a page with simply:And then run:
it populates the select with the newly created option - because it's the only option to select.
You could possibly solve this by adding an "empty" option? But then you have added complexity to deal with this empty option upon submit.