Opened 2 years ago

Last modified 2 years ago

#34025 closed Bug

Bug on autocomplete field when two fields from same reference model are added in same page — at Initial Version

Reported by: Alexandre da Silva Owned by: nobody
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

Example of how to reproduce:

  1. create a model Person.
class Person(models.Model):
    name= models.CharField(max_length=255)
  1. create a model Order with 2 fks pointing to person, for example: supplier and customer
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)
  1. create an admin page for Order.
  1. place the two fields in autocomplete_fields:
class OrderAdmin(admin.ModelAdmin):
    autocomplete_fields = ['supplier', 'customer']
  1. 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 (0)

Note: See TracTickets for help on using tickets.
Back to Top