[Django] #32993: Refactor AutocompleteJsonView to support extra fields in autocomplete response

53 views
Skip to first unread message

Django

unread,
Aug 6, 2021, 4:36:51 AM8/6/21
to django-...@googlegroups.com
#32993: Refactor AutocompleteJsonView to support extra fields in autocomplete
response
------------------------------------------------+------------------------
Reporter: mrts | 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: 1
UI/UX: 0 |
------------------------------------------------+------------------------
Adding data attributes to items in ordinary non-autocomplete foreign key
fields that use {{{forms.widgets.Select}}}-based widgets is relatively
easy. This enables powerful and dynamic admin site customizations where
fields from related models are updated immediately when users change the
selected item.

However, adding new attributes to autocomplete field results currently
requires extending
{{{contrib.admin.views.autocomplete.AutocompleteJsonView}}} and fully
overriding the {{{AutocompleteJsonView.get()}}} method. Here's an example:

{{{#!python
class MyModelAdmin(admin.ModelAdmin):
def get_urls(self):
return [
path('autocomplete/',
CustomAutocompleteJsonView.as_view(admin_site=self.admin_site))
if url.pattern.match('autocomplete/')
else url for url in super().get_urls()
]

class CustomAutocompleteJsonView(AutocompleteJsonView):

def get(self, request, *args, **kwargs):
self.term, self.model_admin, self.source_field, to_field_name =
self.process_request(request)

if not self.has_perm(request):
raise PermissionDenied

self.object_list = self.get_queryset()
context = self.get_context_data()
return JsonResponse({
'results': [
{'id': str(getattr(obj, to_field_name)), 'text': str(obj),
'notes': obj.notes} # <-- customization here
for obj in context['object_list']
],
'pagination': {'more': context['page_obj'].has_next()},
})
}}}


The problem with this is that as {{{AutocompleteJsonView.get()}}} keeps
evolving, there's quite a lot of maintenance overhead required to catch
up.

The solutions is simple, side-effect- and risk-free: adding a result
customization extension point to {{{get()}}} by moving the lines that
construct the results inside {{{JsonResponse}}} to a separate method. So
instead of

{{{#!python
return JsonResponse({
'results': [
{'id': str(getattr(obj, to_field_name)), 'text': str(obj)}
for obj in context['object_list']
],
'pagination': {'more': context['page_obj'].has_next()},
})
}}}

there would be

{{{#!python
return JsonResponse({
'results': [
self.obj_to_dict(obj, to_field_name) for obj in
context['object_list']
],
'pagination': {'more': context['page_obj'].has_next()},
})
}}}

where {{{obj_to_dict()}}} contains the original object to dictionary
conversion code that would be now easy to override:

{{{#!python
def obj_to_dict(self, obj, to_field_name):
return {'id': str(getattr(obj, to_field_name)), 'text': str(obj)}
}}}

The example {{{CustomAutocompleteJsonView}}} from above would now become
succinct and maintainable:

{{{#!python
class CustomAutocompleteJsonView(AutocompleteJsonView):

def obj_to_dict(self, obj, to_field_name):
return super.obj_to_dict(obj, to_field_name) | {'notes':
obj.notes}
}}}

What do you think, is this acceptable? I'm more than happy to provide the
patch.

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

Django

unread,
Aug 6, 2021, 4:42:21 AM8/6/21
to django-...@googlegroups.com
#32993: Refactor AutocompleteJsonView to support extra fields in autocomplete
response
-------------------------------------+-------------------------------------
Reporter: mrts | 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: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by mrts:

Old description:

New description:

class CustomAutocompleteJsonView(AutocompleteJsonView):

construct the results inside {{{JsonResponse}}} constructor to a separate
method. So instead of

there would be

{{{#!python
class CustomAutocompleteJsonView(AutocompleteJsonView):

--

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

Django

unread,
Aug 6, 2021, 10:03:08 AM8/6/21
to django-...@googlegroups.com
#32993: Refactor AutocompleteJsonView to support extra fields in autocomplete
response
--------------------------------------+------------------------------------

Reporter: mrts | Owner: nobody
Type: Cleanup/optimization | Status: new
Component: contrib.admin | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
--------------------------------------+------------------------------------
Changes (by Claude Paroz):

* version: 3.2 => dev
* stage: Unreviewed => Accepted


Comment:

Makes sense to me.

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

Django

unread,
Aug 6, 2021, 11:59:23 AM8/6/21
to django-...@googlegroups.com
#32993: Refactor AutocompleteJsonView to support extra fields in autocomplete
response
-------------------------------+------------------------------------
Reporter: mrts | Owner: nobody
Type: New feature | Status: new

Component: contrib.admin | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by Mariusz Felisiak):

* type: Cleanup/optimization => New feature


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

Django

unread,
Aug 7, 2021, 11:26:05 AM8/7/21
to django-...@googlegroups.com
#32993: Refactor AutocompleteJsonView to support extra fields in autocomplete
response
-------------------------------+------------------------------------
Reporter: mrts | Owner: mrts
Type: New feature | Status: assigned

Component: contrib.admin | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by mrts):

* owner: nobody => mrts
* status: new => assigned


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

Django

unread,
Aug 7, 2021, 12:36:32 PM8/7/21
to django-...@googlegroups.com
#32993: Refactor AutocompleteJsonView to support extra fields in autocomplete
response
-------------------------------+------------------------------------
Reporter: mrts | Owner: (none)
Type: New feature | Status: new

Component: contrib.admin | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by mrts):

* owner: mrts => (none)
* status: assigned => new
* has_patch: 0 => 1


Comment:

[https://github.com/django/django/pull/14752/files PR]

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

Django

unread,
Aug 7, 2021, 3:16:21 PM8/7/21
to django-...@googlegroups.com
#32993: Refactor AutocompleteJsonView to support extra fields in autocomplete
response
-------------------------------+------------------------------------
Reporter: mrts | Owner: mrts
Type: New feature | Status: assigned
Component: contrib.admin | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by Jacob Walls):

* owner: (none) => mrts


* status: new => assigned


Comment:

Just a small note for future: you can keep the ticket assigned to yourself
while you're actively maintaining a PR for it.

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

Django

unread,
Aug 8, 2021, 3:01:59 PM8/8/21
to django-...@googlegroups.com
#32993: Refactor AutocompleteJsonView to support extra fields in autocomplete
response
-------------------------------+------------------------------------
Reporter: mrts | Owner: mrts
Type: New feature | Status: assigned
Component: contrib.admin | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------+------------------------------------

Comment (by mrts):

Thanks for the heads up! Will keep it in mind in the future.

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

Django

unread,
Aug 8, 2021, 3:47:07 PM8/8/21
to django-...@googlegroups.com
#32993: Refactor AutocompleteJsonView to support extra fields in autocomplete
response
-------------------------------+------------------------------------
Reporter: mrts | Owner: mrts
Type: New feature | Status: assigned
Component: contrib.admin | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------+------------------------------------
Description changed by mrts:

Old description:

> Adding data attributes to items in ordinary non-autocomplete foreign key

> construct the results inside {{{JsonResponse}}} constructor to a separate

New description:

class CustomAutocompleteJsonView(AutocompleteJsonView):

construct the results inside {{{JsonResponse}}} constructor to a separate
method. So instead of

{{{#!python
return JsonResponse({
'results': [
{'id': str(getattr(obj, to_field_name)), 'text': str(obj)}
for obj in context['object_list']
],
'pagination': {'more': context['page_obj'].has_next()},
})
}}}

there would be

{{{#!python
return JsonResponse({
'results': [
self.serialize_result(obj, to_field_name) for obj in


context['object_list']
],
'pagination': {'more': context['page_obj'].has_next()},
})
}}}

where {{{serialize_result()}}} contains the original object to dictionary


conversion code that would be now easy to override:

{{{#!python
def serialize_result(self, obj, to_field_name):


return {'id': str(getattr(obj, to_field_name)), 'text': str(obj)}
}}}

The example {{{CustomAutocompleteJsonView}}} from above would now become
succinct and maintainable:

{{{#!python
class CustomAutocompleteJsonView(AutocompleteJsonView):

def serialize_result(self, obj, to_field_name):
return super.serialize_result(obj, to_field_name) | {'notes':
obj.notes}
}}}

What do you think, is this acceptable? I'm more than happy to provide the
patch.

--

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

Django

unread,
Aug 9, 2021, 1:18:11 AM8/9/21
to django-...@googlegroups.com
#32993: Refactor AutocompleteJsonView to support extra fields in autocomplete
response
--------------------------------------+------------------------------------
Reporter: mrts | Owner: mrts
Type: Cleanup/optimization | Status: assigned

Component: contrib.admin | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
--------------------------------------+------------------------------------
Changes (by Mariusz Felisiak):

* type: New feature => Cleanup/optimization


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

Django

unread,
Aug 9, 2021, 1:33:56 AM8/9/21
to django-...@googlegroups.com
#32993: Refactor AutocompleteJsonView to support extra fields in autocomplete
response
--------------------------------------+------------------------------------
Reporter: mrts | Owner: mrts
Type: Cleanup/optimization | Status: assigned
Component: contrib.admin | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 0

Easy pickings: 1 | UI/UX: 0
--------------------------------------+------------------------------------
Changes (by Mariusz Felisiak):

* needs_tests: 0 => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/32993#comment:10>

Django

unread,
Aug 10, 2021, 1:52:40 AM8/10/21
to django-...@googlegroups.com
#32993: Refactor AutocompleteJsonView to support extra fields in autocomplete
response
-------------------------------------+-------------------------------------
Reporter: mrts | Owner: mrts
Type: | Status: assigned
Cleanup/optimization |

Component: contrib.admin | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* needs_tests: 1 => 0
* stage: Accepted => Ready for checkin


--
Ticket URL: <https://code.djangoproject.com/ticket/32993#comment:11>

Django

unread,
Aug 10, 2021, 2:59:43 AM8/10/21
to django-...@googlegroups.com
#32993: Refactor AutocompleteJsonView to support extra fields in autocomplete
response
-------------------------------------+-------------------------------------
Reporter: mrts | Owner: mrts
Type: | Status: closed

Cleanup/optimization |
Component: contrib.admin | Version: dev
Severity: Normal | Resolution: fixed

Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak <felisiak.mariusz@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"9b1158a7e0784686bbe5118a88d4804b99fa4fe1" 9b1158a7]:
{{{
#!CommitTicketReference repository=""
revision="9b1158a7e0784686bbe5118a88d4804b99fa4fe1"
Fixed #32993 -- Added AutocompleteJsonView.serialize_result() to allow
customization.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/32993#comment:12>

Reply all
Reply to author
Forward
0 new messages