Shared task
Fixed #32993 -- Added AutocompleteJsonView.serialize_result() to allow customization.
PR #14752 ↗ · django/django · · merged Aug 10, 2021 · +35 −3 · base b64db05b9ced
what a new run launched now would send
Refactor AutocompleteJsonView to support extra fields in autocomplete response
Description
(last modified by mrts)
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:
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 constructor to a separate method. So instead of
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
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:
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:
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.
Work only inside this repository checkout. Make the code change the task
describes, keeping the diff focused — no drive-by refactors.
When you are done, leave your changes committed or in the working tree;
they are collected automatically.
Stay on this snapshot checkout (`task/ycb_django_pr14752`). Never checkout, pull, or rebase onto `main`. That branch is a README-only orphan.
Stay on this HEAD. Do not fetch another default branch. Push only on the Cursor-created `crazy-cursor/…` side branch from this HEAD.Some past runs of this task were launched with a different prompt (the prompt template changed since, or those runs predate this benchmark's stored prompt). Each run persists the exact prompt it sent at launch — that per-launch record is the audit trail; this page shows only the current one.
| Run | Model | Verdict |
|---|---|---|
| Aug 21, 12:31 UTC · completed | composer-2.5 | PASS |
| Aug 21, 12:31 UTC · completed | grok-4.6 | PASS |
| Aug 21, 12:31 UTC · completed | grok-4.6-low |
Powered by YourCodingBench — benchmark coding models on your own repo's commits. sign in
| Aug 21, 12:31 UTC · completed | grok-4.6-medium | PASS |
| Aug 21, 12:31 UTC · completed | grok-4.6-xhigh | PASS |
Binary verdicts from the pinned judge (D27). Full attempt detail — candidate diff, transcript, timings — lives on each run page's score matrix.