#34025: Bug on autocomplete field when two fields from same reference model are
added in same page
-------------------------------------+-------------------------------------
     Reporter:  lexrupy              |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Uncategorized        |                  Version:  4.1
     Severity:  Normal               |               Resolution:
     Keywords:  admin, autocomplete  |             Triage Stage:
                                     |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  1
-------------------------------------+-------------------------------------
Description changed by lexrupy:

Old description:

> Example of how to reproduce:
>
> 1. create a model Person.
>
> {{{
> class Person(models.Model):
>     name= models.CharField(max_length=255)
> }}}
>
> 2. 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)
> }}}
>
> 3. create an admin page for Order.
>
> 4. place the two fields in autocomplete_fields:
>
> {{{
> class OrderAdmin(admin.ModelAdmin):
>     autocomplete_fields = ['supplier', 'customer']
> }}}
>
> 5. 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;
>         });
>     }
> }}}

New description:

 Example of how to reproduce:

 1. create a model Person.

 2. 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)
 }}}

 3. create an admin page for Order.

 4. 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)
 }}}

 5. 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;
         });
     }
 }}}

--

-- 
Ticket URL: <https://code.djangoproject.com/ticket/34025#comment:1>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/010701835cc76933-3452b0d4-405f-4116-8194-ef198efa813c-000000%40eu-central-1.amazonses.com.

Reply via email to