#32343: Chained autocomplete_fields in contrib.admin
-------------------------------+--------------------------------------
Reporter: adontz | Owner: nobody
Type: New feature | Status: new
Component: contrib.admin | Version: 3.1
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Description changed by adontz:
Old description:
> Sometimes querysets for autocomplete_fields should be dependent and
> selection should be chained.
>
> Imagine there is a model Address with references to Country and City
> models
> {{{
> class Country(models.Model):
> id = models.AutoField(primary_key=True)
> name = models.CharField(max_length=100)
>
> class City(models.Model):
> id = models.AutoField(primary_key=True)
> country = models.ForeignKey(Country, on_delete=models.CASCADE)
> name = models.CharField(max_length=100)
>
> class Address(models.Model):
> id = models.AutoField(primary_key=True)
> country = models.ForeignKey(Country, on_delete=models.CASCADE)
> city = models.ForeignKey(City, on_delete=models.CASCADE, null=True,
> blank=True)
> }}}
> Also imagine admin form displays a Country drop-down with the list of all
> countries and a City drop-downwith. A user reasonably expects City drop-
> down to contain the list of all cities within previously selected
> country, but not all cities in the entire world.
>
> Unfortunately, when current version of Django calls
> /admin/app/model/autocomplete no information about current selection in
> other drop-downs is sent, so there is no way to select cities of a
> specific country for a new unsaved model. So overriding "def
> get_search_results(self, request, queryset, search_term)" gives nothing,
> as required information is not available.
>
> However, a small change to autocomplete.js allowed me to easily implement
> what I need.
> {{{
> 'use strict';
> {
> const $ = django.jQuery;
> const init = function($element, options) {
> const settings = $.extend({
> ajax: {
> data: function(params) {
> var result = {
> 'term': params.term,
> 'page': params.page
> };
>
> $('.admin-autocomplete').each(function(index) {
> result['selected_' + $(this).attr('name')] =
> $(this).val(); // Pass selections of all other select2 with request.
> });
>
> return result;
> }
> }
> }, options);
> $element.select2(settings);
> };
> ...
> // the rest is not changed
> }}}
> Now, in "def get_search_results(self, request, queryset, search_term)" I
> can extract all required information from "request.GET"
>
> I am no sure neither about if all autocomplete selects should be
> included, if all selects should be included. Probably it would be better
> to introduce some kind of opt-in configuration. Also, I am not sure about
> "selected_" prefix. I understand that this is not a generic code which
> should be included in the next version of Django. However, this small
> change works pretty fine for me, allowing to build much more friendly
> admin forms. I am ready to present pull request, if maintainers will be
> so kind to comment on idea in general and point at issues I have missed.
New description:
Sometimes querysets for autocomplete_fields should be dependent and
selection should be chained.
Imagine there is a model Address with references to Country and City
models
{{{
class Country(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100)
class City(models.Model):
id = models.AutoField(primary_key=True)
country = models.ForeignKey(Country, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
class Address(models.Model):
id = models.AutoField(primary_key=True)
country = models.ForeignKey(Country, on_delete=models.CASCADE)
city = models.ForeignKey(City, on_delete=models.CASCADE, null=True,
blank=True)
}}}
Also imagine admin form displays a Country drop-down with the list of all
countries and a City drop-downwith. A user reasonably expects City drop-
down to contain the list of all cities within previously selected country,
but not all cities in the entire world.
Unfortunately, when current version of Django calls
/admin/app/model/autocomplete no information about current selection in
other drop-downs is sent, so there is no way to select cities of a
specific country for a new unsaved model. So overriding "def
get_search_results(self, request, queryset, search_term)" gives nothing,
as required information is not available.
However, a small change to autocomplete.js allowed me to easily implement
what I need.
{{{
'use strict';
{
const $ = django.jQuery;
const init = function($element, options) {
const settings = $.extend({
ajax: {
data: function(params) {
var result = {
'term': params.term,
'page': params.page
};
$('.admin-autocomplete').each(function(index) {
result['selected_' + $(this).attr('name')] =
$(this).val(); // Pass selections of all other select2 with request.
});
return result;
}
}
}, options);
$element.select2(settings);
};
...
// the rest is not changed
}}}
Now, in "def get_search_results(self, request, queryset, search_term)" I
can extract all required information from "request.GET"
I am not sure neither about if all autocomplete selects should be
included, nor if all selects should be included. Probably it would be
better to introduce some kind of opt-in configuration. Also, I am not sure
about "selected_" prefix. I understand that this is not a generic code
which should be included in the next version of Django. However, this
small change works pretty fine for me, allowing to build much more
friendly admin forms. I am ready to present pull request, if maintainers
will be so kind to comment on idea in general and point at issues I have
missed.
--
--
Ticket URL: <https://code.djangoproject.com/ticket/32343#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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/064.8d78c4bd0b9106ea6cf3422b8982b0a1%40djangoproject.com.