[Django] #32628: Add extra data to autocomplete request

289 views
Skip to first unread message

Django

unread,
Apr 9, 2021, 11:01:51 AM4/9/21
to django-...@googlegroups.com
#32628: Add extra data to autocomplete request
------------------------------------------------+------------------------
Reporter: Seb G | Owner: nobody
Type: Cleanup/optimization | Status: new
Component: contrib.admin | Version: 3.2
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
------------------------------------------------+------------------------
More often than not, I need to add extra parameters to requests sent by
autocomplete widgets from admin forms. Currently I have 2 options to do
so:

1. Listen to opening/closing Select2 events to add headers to the request:

{{{#!javascript
$(document).on("select2:opening", "#foo_set-group select.admin-
autocomplete", function () {
$.ajaxSetup({headers: {"X-Foo": "bar"}});
}
).on("select2:closing", "#foo_set-group select.admin-autocomplete",
function () {
delete $.ajaxSettings.headers["X-Foo"];
}
);
}}}

2. Destroy the widget and rebuild it using `$.fn.djangoAdminSelect2` to
hack my extra parameters next to the other expected GET parameters:

{{{#!python
let $select = $("#id_my_field");
$select.select2("destroy").djangoAdminSelect2({
ajax: {
data: function (params) {
return {
term: params.term
page: params.page
app_label: $select.data("app-label"),
model_name: $select.data("model-name"),
field_name: $select.data("field-name")
foo: "bar"
}
}
}
});
}}}

None of these solutions look clean to me, and I would definitely like to
have the ability to add extra parameters to `$.fn.djangoAdminSelect2`
properly as follows:

- `autocomplete.js`:

{{{#!javascript
'use strict';
{
const $ = django.jQuery;
const init = function($element, options, extraParams) {
const settings = $.extend({
ajax: {
data: function(params) {
let defaultParams = {
term: params.term,
page: params.page,
app_label: $element.data('app-label'),
model_name: $element.data('model-name'),
field_name: $element.data('field-name')
};
return $.extend(defaultParams, extraParams)
}
}
}, options);
$element.select2(settings);
};

$.fn.djangoAdminSelect2 = function(options, extraParams) {
const settings = $.extend({}, options);
$.each(this, function(i, element) {
const $element = $(element);
init($element, settings, extraParams);
});
return this;
};

$(function() {
// Initialize all autocomplete widgets except the one in the
template
// form used when a new formset is added.
$('.admin-
autocomplete').not('[name*=__prefix__]').djangoAdminSelect2();
});

$(document).on('formset:added', (function() {
return function(event, $newFormset) {
return $newFormset.find('.admin-
autocomplete').djangoAdminSelect2();
};
})(this));
}
}}}

- `consumer_script.js`:


{{{#!javascript
$select = $("#id_my_field");
$select.select2("destroy").djangoAdminSelect2({}, {foo: "bar"});
}}}

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

Django

unread,
Apr 9, 2021, 11:41:30 AM4/9/21
to django-...@googlegroups.com
#32628: Add extra data to autocomplete request
-------------------------------------+-------------------------------------

Reporter: Seb G | Owner: nobody
Type: | Status: new
Cleanup/optimization |
Component: contrib.admin | Version: 3.2
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
-------------------------------------+-------------------------------------

Comment (by Jan Staal):

There is another solution direction mentioned here:

https://stackoverflow.com/questions/55344987/how-to-filter-modeladmin-
autocomplete-fields-results-with-the-context-of-limit-c/55476825#55476825

--
Ticket URL: <https://code.djangoproject.com/ticket/32628#comment:1>

Django

unread,
Apr 12, 2021, 1:12:58 AM4/12/21
to django-...@googlegroups.com
#32628: Add extra data to autocomplete request
-------------------------------------+-------------------------------------

Reporter: Seb G | Owner: nobody
Type: | Status: closed
Cleanup/optimization |
Component: contrib.admin | Version: 3.2
Severity: Normal | Resolution: duplicate

Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* cc: Johannes Maron (added)
* status: new => closed
* resolution: => duplicate


Comment:

Thanks for this proposition, however I don't think that JavaScript is the
right place to inject extra parameters. I would rather customize
`ModelAdmin.autocomplete_view()` and `AutocompleteJsonView`.

Closing as a duplicate of #29700 as documenting `AutocompleteJsonView` and
`ModelAdmin.autocomplete_view()` should fix this issue.

--
Ticket URL: <https://code.djangoproject.com/ticket/32628#comment:2>

Django

unread,
Apr 12, 2021, 2:36:20 AM4/12/21
to django-...@googlegroups.com
#32628: Add extra data to autocomplete request
-------------------------------------+-------------------------------------

Reporter: Seb G | Owner: nobody
Type: | Status: closed
Cleanup/optimization |
Component: contrib.admin | Version: 3.2
Severity: Normal | Resolution: duplicate

Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Seb G):

Thanks for both answers. However, I respectfully disagree with both of
them since both solutions are implemented back-end side and hence lack
flexibility for some scenario (including the ones I was opening this
ticket for).

Simplest example: I want to dynamically add the value of another field of
the form as an extra GET parameter to the autocomplete, to implement some
sort of fields-coupling.

--
Ticket URL: <https://code.djangoproject.com/ticket/32628#comment:3>

Django

unread,
Apr 12, 2021, 3:22:06 AM4/12/21
to django-...@googlegroups.com
#32628: Add extra data to autocomplete request
-------------------------------+--------------------------------------

Reporter: Seb G | Owner: nobody
Type: New feature | Status: closed
Component: contrib.admin | Version: 3.2
Severity: Normal | Resolution: wontfix

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by Mariusz Felisiak):

* type: Cleanup/optimization => New feature
* resolution: duplicate => wontfix


Comment:

> Thanks for both answers. However, I respectfully disagree with both of
them since both solutions are implemented back-end side and hence lack
flexibility for some scenario (including the ones I was opening this
ticket for).
>
> Simplest example: I want to dynamically add the value of another field
of the form as an extra GET parameter to the autocomplete, to implement
some sort of fields-coupling.

Agreed, there is a use case that is not covered by the current
implementation, however the Django Admin is not a
[https://docs.djangoproject.com/en/3.2/ref/contrib/admin/#module-
django.contrib.admin universal tool for building an app]. You can always
override `autocomplete.js` in your project.

--
Ticket URL: <https://code.djangoproject.com/ticket/32628#comment:4>

Django

unread,
Apr 12, 2021, 6:40:58 AM4/12/21
to django-...@googlegroups.com
#32628: Add extra data to autocomplete request
-------------------------------+--------------------------------------

Reporter: Seb G | Owner: nobody
Type: New feature | Status: closed
Component: contrib.admin | Version: 3.2
Severity: Normal | Resolution: wontfix

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------

Comment (by Johannes Maron):

Hi there,

The author of both the autocomplete integration as well as the django-
select2 package here.
So, I understand you point and frustration. However, the second solution
you are proposing actually looks a lot cleaner to me, than to arbitrarily
add a second options object.

Just of consistency I would keep the options we pass to
`djangoAdminSelect2` the same as the once you'd pass to `select2`. It
would make it very confusing for many folk if we break with the `select2`
API.

All that aside, this is not a public API. Therefore, your best bet is to
overwrite the whole file, if you need some special implementation or use
`django-select2` or your special needs.

Please, if you want to change the options object structure, I must kindly
ask you to try your luck with the Select2 project first. We simply don't
have the resources to maintain a custom implementation.

Best,
Joe

--
Ticket URL: <https://code.djangoproject.com/ticket/32628#comment:5>

Django

unread,
Apr 13, 2021, 8:01:25 AM4/13/21
to django-...@googlegroups.com
#32628: Add extra data to autocomplete request
-------------------------------+--------------------------------------

Reporter: Seb G | Owner: nobody
Type: New feature | Status: closed
Component: contrib.admin | Version: 3.2
Severity: Normal | Resolution: wontfix

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------

Comment (by Seb G):

Thanks for clarifying the situation Johannes. I'll stick with my own
override then :-)

--
Ticket URL: <https://code.djangoproject.com/ticket/32628#comment:6>

Django

unread,
Apr 22, 2021, 9:57:16 AM4/22/21
to django-...@googlegroups.com
#32628: Add extra data to autocomplete request
-------------------------------+--------------------------------------

Reporter: Seb G | Owner: nobody
Type: New feature | Status: closed
Component: contrib.admin | Version: 3.2
Severity: Normal | Resolution: wontfix

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------

Comment (by Seb G):

Dear Johannes,

I found the following code to both add the requested feature (being able
to add extra GET params to the AJAX request) **and** preserve Select2 API.

I also took the liberty of passing the `true` parameter to the `$.extend`
call that merges default Django settings with user-defined settings in the
`init` function (line 11), since omitting it caused a bug where other
parameters (passed through `options`) nested under the `ajax` key were
overwritten to `undefined` (see relevant documentation here:
https://api.jquery.com/jQuery.extend/#jQuery-extend-deep-target-
object1-objectN).

- `autocomplete.js`:

{{{#!javascript
'use strict';
{
const $ = django.jQuery;

const init = function($element, options) {
let userData = function (params) {};
if (options.ajax && options.ajax.data) {
userData = options.ajax.data;
delete options.ajax.data;
}

const settings = $.extend(true, {
ajax: {
data: function(params) {
const defaultData = {


term: params.term,
page: params.page,
app_label: $element.data('app-label'),
model_name: $element.data('model-name'),
field_name: $element.data('field-name')
};

return $.extend(defaultData, userData(params))
}
}
}, options);

$element.select2(settings);
};

$.fn.djangoAdminSelect2 = function(options) {


const settings = $.extend({}, options);
$.each(this, function(i, element) {
const $element = $(element);

init($element, settings);
});
return this;
};

$(function() {
// Initialize all autocomplete widgets except the one in the
template
// form used when a new formset is added.
$('.admin-
autocomplete').not('[name*=__prefix__]').djangoAdminSelect2();
});

$(document).on('formset:added', (function() {
return function(event, $newFormset) {
return $newFormset.find('.admin-
autocomplete').djangoAdminSelect2();
};
})(this));
}
}}}

- `consumer_script.js`:

{{{#!javascript
$select = $("#id_my_field");
$select.select2("destroy").djangoAdminSelect2({

ajax: {
data: function (params) {
return {foo: "bar"}
}
// Adding other AJAX settings is now also possible, such as
processResults for example
processResults: function (data) {
console.log("Now possible")
return data
}
}
});
}}}

Do you think this approach would be compatible with your flow?

Regards

--
Ticket URL: <https://code.djangoproject.com/ticket/32628#comment:7>

Django

unread,
Apr 27, 2021, 5:23:59 AM4/27/21
to django-...@googlegroups.com
#32628: Add extra data to autocomplete request
-------------------------------+--------------------------------------

Reporter: Seb G | Owner: nobody
Type: New feature | Status: new
Component: contrib.admin | Version: 3.2
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
-------------------------------+--------------------------------------
Changes (by Seb G):

* status: closed => new
* resolution: wontfix =>


Comment:

For the record, I submitted a PR which was rejected since the flow seems
to be that an agreement should be reached here on Trac before moving on to
a PR. So could you please take a look either at the code here or at the
PR?

Link to the PR: https://github.com/django/django/pull/14305

--
Ticket URL: <https://code.djangoproject.com/ticket/32628#comment:8>

Django

unread,
Apr 27, 2021, 5:59:47 AM4/27/21
to django-...@googlegroups.com
#32628: Add extra data to autocomplete request
-------------------------------+--------------------------------------

Reporter: Seb G | Owner: nobody
Type: New feature | Status: closed
Component: contrib.admin | Version: 3.2
Severity: Normal | Resolution: wontfix

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by Mariusz Felisiak):

* status: new => closed
* resolution: => wontfix


Comment:

[https://docs.djangoproject.com/en/stable/internals/contributing/triaging-
tickets/#closing-tickets Please follow triaging guidelines with regards to
wontfix tickets.]

--
Ticket URL: <https://code.djangoproject.com/ticket/32628#comment:9>

Reply all
Reply to author
Forward
0 new messages