Opened 4 years ago
Last modified 4 years ago
#32343 closed New feature
Chained autocomplete_fields in contrib.admin — at Initial Version
Reported by: | Roman | Owned by: | nobody |
---|---|---|---|
Component: | contrib.admin | Version: | 3.1 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
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.