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;
});
}
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/34025>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
Old description:
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)
}}}
--
--
Ticket URL: <https://code.djangoproject.com/ticket/34025#comment:1>
* component: Uncategorized => contrib.admin
Comment:
A couple of points here:
- 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.
- This appears to be because both fields are required. If you make the fks
`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:
{{{
<select></select>
}}}
And then run:
{{{
document.querySelector('select').options.add(new Option('test'))
}}}
it populates the select with the newly created option - because it's the
only option to select.
--
Ticket URL: <https://code.djangoproject.com/ticket/34025#comment:2>
Comment (by David Sanders):
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.
--
Ticket URL: <https://code.djangoproject.com/ticket/34025#comment:3>
Comment (by David Sanders):
PR: https://github.com/django/django/pull/16079
--
Ticket URL: <https://code.djangoproject.com/ticket/34025#comment:4>
* has_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/34025#comment:5>
* owner: nobody => David Sanders
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/34025#comment:6>
Comment (by Alexandre da Silva):
''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:
1. create a new record for order
2. select an existing supplier on select combobox, then click on edit.
3. 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.
--
Ticket URL: <https://code.djangoproject.com/ticket/34025#comment:7>
Comment (by David Sanders):
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.
--
Ticket URL: <https://code.djangoproject.com/ticket/34025#comment:8>
Comment (by Alexandre da Silva):
Hello David,
I already tested yesterday. It worked
--
Ticket URL: <https://code.djangoproject.com/ticket/34025#comment:9>
Comment (by David Sanders):
Thanks Alexandre, will wait for a member of the triage team… Djangocon is
on atm so we may need to be patient :)
--
Ticket URL: <https://code.djangoproject.com/ticket/34025#comment:10>