#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.

Reply via email to