Opened 11 months ago

Last modified 4 months ago

#29700 assigned Cleanup/optimization

Document ModelAdmin.autocomplete_view() and AutocompleteJsonView (as customisation point).

Reported by: David W. Lloyd Owned by: Alexandru Balan
Component: Documentation Version: master
Severity: Normal Keywords:
Cc: Johannes Hoppe Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

Reference: https://code.djangoproject.com/ticket/29010#comment:7

The new autocomplete view uses whatever ordering the ModelAdmin specifies, but most of the time you'd want autocomplete to be alphabetized so that typeahead suggestions make more sense and can be scanned visually. My particular use case is that I want certain admins to default to showing the most recently edited objects, but this sort order makes no sense for autocomplete views in lookups from related object change forms.

This seems like a common enough use case to warrant built-in decoupling of sort order for autocomplete view from ModelAdmin's standard "ordering" field.

Proposed improvement/feature would be an "autocomplete_ordering" field and corresponding "get_autocomplete_ordering" method which default to using the "ordering" but can be easily overridden, readily providing decoupling when needed.

Change History (7)

comment:1 Changed 11 months ago by Carlton Gibson

Cc: Johannes Hoppe added

The use-case here seems reasonable enough, but I'm (initially) sceptical about adding yet more API to ModelAdmin.

If that weren't an option, what would I do?

Well, I'd look to customise the autocomplete view:

    def autocomplete_view(self, request):
        return AutocompleteJsonView.as_view(model_admin=self)(request)

source

Is there any reason I can't just override `AutocompleteJsonView.get_queryset()` to apply whatever ordering I need? (It doesn't look like there is...)

autocomplete_view()/AutocompleteJsonView/&co are not documented, so this ticket would amount to needing to add that (and maybe we make small adjustments to the ModelAPI) but (for me, initially) this would help to modularise the autocomplete options and be preferable to more top-level ModelAdmin options.

Thoughts?

Version 0, edited 11 months ago by Carlton Gibson (next)

comment:2 in reply to:  1 ; Changed 11 months ago by Johannes Hoppe

Replying to Carlton Gibson:

The use case here seems reasonable enough, but I'm (initially) skeptical about adding yet more API to ModelAdmin.

That is a reasonable concern. The ModelAdmin is practically exploding. However that should not keep us from making changes, but only from blindly adding features.
Maybe there is a better way though as you suggested later.

If that weren't an option, what would I do?

Well, I'd look to customise the autocomplete view:

    def autocomplete_view(self, request):
        return AutocompleteJsonView.as_view(model_admin=self)(request)

source

Is there any reason I can't just override `AutocompleteJsonView.get_queryset()` to apply whatever ordering I need? (It doesn't look like there is...)

autocomplete_view()/AutocompleteJsonView/&co are not documented, so this ticket would amount to needing to add that (and maybe we make small adjustments to the ModelAPI) but (for me, initially) this would help to modularise the autocomplete options and be preferable to more top-level ModelAdmin options.

Thoughts?

That is not a bad way, this is how I would go about it myself too. Actually this way you can add all sorts of extra functionality.

Last edited 11 months ago by Johannes Hoppe (previous) (diff)

comment:3 in reply to:  2 Changed 11 months ago by David W. Lloyd

Replying to Johannes Hoppe:

Replying to Carlton Gibson:

Thoughts?

That is not a bad way, this is how I would go about it myself too. Actually this way you can add all sorts of extra functionality.

I agree, that's a fine way to achieve the functionality, and if AutocompleteJsonView gets a bit more documentation, I guess that would be the default approach?

But my thinking is as follows: you can make the same exact argument about the *existing* "ordering" field - why have it, when you can do the same thing by modifying the queryset?

I personally believe the answer is: "Because it's a common enough use case that having a dedicated field makes it easier, more intuitive, and more explicit" - all of which are good things, and I think they apply to the autocomplete sorting the same as they do the ModelAdmin sorting.

Yes, that comes at the cost of adding another field to the API, but that's going to be the case with anything you want to make more explicit/intuitive. If there was an interest in conserving fields, it could be a dict? like:

autocomplete_view_options = {'ordering': 'name, 'other_useful_parameter_to_be_added_in_future': 'maybe?'}

...either way, while I see how to achieve the functionality in question myself (thanks!) and will have no problem whatsoever doing so, I still believe that the explicit decoupling would make sense, either via a single "autocomplete_ordering" field or a dict of extensible options including, initially, ordering. Other candidates might include caching, or perhaps providing a template.html to format each of the results within the select2 widget.

Last edited 11 months ago by David W. Lloyd (previous) (diff)

comment:4 Changed 11 months ago by Carlton Gibson

Component: contrib.adminDocumentation
Summary: Provide an "autocomplete_ordering" value in ModelAdmin, to decouple autocomplete ordering from admin orderingDocument ModelAdmin.autocomplete_view() and AutocompleteJsonView (as customisation point).
Triage Stage: UnreviewedAccepted
Type: New featureCleanup/optimization
Version: 2.1master

...you can make the same exact argument about the *existing* "ordering" field - why have it, when you can do the same thing by modifying the queryset?

I think in the history of ModelAdmin itself, we've learnt that it's possible to have too much of a good thing when it comes to these declarative options.

ordering has been there forever, and there's no realistic way we can take it out. But I don't think it's likely we'd add it again today.

Instead I think we'd point to overriding get_queryset(), and just using a orderBy.

def get_queryset(self): 
    return self.model.objects.orderBy('-name') 

(... or such ...)

That would do. It's roughly the same, or sometime less, code than specifying ordering & co.
It's less magic. Less to remember. And less to have to go searching for when things behave unexpectedly.

Mutatis mutandis, I think in this case we should document ModelAdmin.autocomplete_view() and AutocompleteJsonView as the customisation point for the behaviour here.

(If there are one or two key configuration options then possibly AutocompleteJsonView could take init kwargs to as_view() to avoid subclassing in every case, but any such addition would need assessing separately, and probably afterwards.)

comment:5 Changed 5 months ago by Alexandru Balan

Owner: changed from nobody to Alexandru Balan
Status: newassigned

comment:6 Changed 4 months ago by Tim Graham

Has patch: set

comment:7 Changed 4 months ago by Tim Graham

Patch needs improvement: set
Note: See TracTickets for help on using tickets.
Back to Top