Opened 10 months ago

Last modified 2 months ago

#29010 new New feature

Allow customizing the autocomplete search results based on the querying model

Reported by: Muslu Y. Owned by: nobody
Component: contrib.admin Version: 2.0
Severity: Normal Keywords: ForeignKey, get_search_results, search_fields
Cc: Johannes Hoppe Triage Stage: Someday/Maybe
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I have A,B,C models. A and B models are using C model's ForeignKey for autocomplete.

How can i find which model is querying?

Change History (14)

comment:1 Changed 10 months ago by Muslu Y.

Summary: Which models is using search_fields to get_search_resultsWhich models is querying search_fields to autocomplete?

comment:3 Changed 10 months ago by Muslu Y.

I think Autocomplete is not enough right now.

models.py

class A(models.Model):
    a_name = models.CharField(max_length=100)

class B(models.Model):
    b_name   =   models.ManyToManyField(A)
    
class C(models.Model):
    c_name   =   models.ManyToManyField(A)

admin.py

class AAdmin(admin.ModelAdmin):
    search_fields       =   ['a_name']

    def get_search_results(self, request, queryset, search_term):
        queryset, use_distinct  =   super().get_search_results(request, queryset, search_term)
        
        ## how can i learn which models (B or C) querying for a_name?
        ## because i want to separately filter for every model


class BAdmin(admin.ModelAdmin):
    autocomplete_fields    =   ['b_name']
    
class CAdmin(admin.ModelAdmin):
    autocomplete_fields    =   ['c_name']

comment:4 Changed 10 months ago by Tim Graham

Cc: Johannes Hoppe added
Component: Database layer (models, ORM)contrib.admin
Summary: Which models is querying search_fields to autocomplete?Allow customizing the autocomplete search results based on the querying model

I see. I guess it might be possible to add a hint of the model where the query is coming from in a GET parameter. That would be untrusted though.

comment:5 Changed 8 months ago by Tim Graham

Triage Stage: UnreviewedAccepted

comment:6 Changed 8 months ago by Johannes Hoppe

Triage Stage: AcceptedSomeday/Maybe

Hi there,

currently you don't explicitly know who is calling this method, since it's all called from the same view. Both Widgets call the same view as the view is on AAdmin.
So this is conceptually not supported. That doesn't mean it doesn't work. You can always check https://en.wikipedia.org/wiki/HTTP_referer

To add a bit more context here, we did have an intermediate solution that would have made this easier. A view per widget. We ultimately dropped that approach to decrease complexity. A decision I still support.

My suggestion would be use an external library like django-select2 or django-autocomplete if you want to implement more sophisticated logic.
Please also keep in mind, the admin is not recommend to be used for sofistikated user interfaces.

Anyhow, at the moment I would strongly advice against adding a "hint" to the request. Since it's not safe against request forging and can lead to unintended security issues.

comment:7 in reply to:  6 ; Changed 2 months ago by David W. Lloyd

Replying to Johannes Hoppe:

To add a bit more context here, we did have an intermediate solution that would have made this easier. A view per widget. We ultimately dropped that approach to decrease complexity. A decision I still support.

Was there no in-between option? This severely limits the usefulness of the widget... as a separate-but-related issue:

  • the new autocomplete widget ignores any filtering done in the "limit_choices_to" ORM definition, unlike a regular select field; not very DRY, since limit_choices_to can, with other widgets, be used to filter lookups effectively... inconsistent, unintuitive behavior. If you're not going to fix it, perhaps update the autocomplete documentation to mention that limit_choices_to is completely ignored...
  • the new autocomplete widget ties its ordering of results to the ModelAdmin in question, which is also unintuitive if your ModelAdmin has a default ordering other than alphabetical... for example, if you want the ModelAdmin to default to showing the newest entries, your autocomplete results will ALSO be ordered thus, but such sorting is extremely confusing and unlikely to be helpful in a type-ahead scenario

Your proposal to use django-select2 or DAL almost makes me wonder: why add autocomplete to the admin at all, then? It's 2018, this is a standard design pattern for administrative backends, and to omit the ability to filter based on referring entity, to ignore limit_choices_to, and to tightly couple autocomplete result sorting to default ModelAdmin result sorting seems highly counterintuitive in a pretty common set of use cases.

My suggestion would be use an external library like django-select2 or django-autocomplete if you want to implement more sophisticated logic.
Please also keep in mind, the admin is not recommend to be used for sofistikated user interfaces.

Based on the packages out there targeting the admin & the extensive articles on customizing it, that recommendation just seems optimistic. Django's built-in admin is hailed as one of its selling points, and the fact that it HAS a strong built-in solution has probably discouraged the creation of third-party standalone packages targeting scaffolding & building admin backends - why reinvent the wheel? This recommendation seems to ignore reality - many folks are using the admin to build complex interfaces, the autocomplete in 2.0 *can* really help us all out, but it's a little half-baked at the moment. Baking it some more, to allow for filtering based on relation and decoupled sorting, seems like a high-value enhancement...

comment:8 in reply to:  7 ; Changed 2 months ago by Johannes Hoppe

Replying to David W. Lloyd:

Replying to Johannes Hoppe:

To add a bit more context here, we did have an intermediate solution that would have made this easier. A view per widget. We ultimately dropped that approach to decrease complexity. A decision I still support.

Was there no in-between option? This severely limits the usefulness of the widget... as a separate-but-related issue:

I agree, but this feature took ten years to be implemented. We decreased scope to decrease complexity. Now that it's out we can see what additional features get requested and chose to work on those.

  • the new autocomplete widget ignores any filtering done in the "limit_choices_to" ORM definition, unlike a regular select field; not very DRY, since limit_choices_to can, with other widgets, be used to filter lookups effectively... inconsistent, unintuitive behavior. If you're not going to fix it, perhaps update the autocomplete documentation to mention that limit_choices_to is completely ignored...

I agree this is a problem. I would much welcome a fix here to. It seems we all missed in the reviews.

  • the new autocomplete widget ties its ordering of results to the ModelAdmin in question, which is also unintuitive if your ModelAdmin has a default ordering other than alphabetical... for example, if you want the ModelAdmin to default to showing the newest entries, your autocomplete results will ALSO be ordered thus, but such sorting is extremely confusing and unlikely to be helpful in a type-ahead scenario

The sorting is only there for pagination purposes but it can be used to improve results. I use the widgets on full text indexes too, which go way beyond a simple typeahead.

Your proposal to use django-select2 or DAL almost makes me wonder: why add autocomplete to the admin at all, then? It's 2018, this is a standard design pattern for administrative backends, and to omit the ability to filter based on referring entity, to ignore limit_choices_to, and to tightly couple autocomplete result sorting to default ModelAdmin result sorting seems highly counterintuitive in a pretty common set of use cases.

Go ahead an decouple it. That's an easy one. You add a new method that by defaults calls the current soring method. Please open a separate issue for that one. I would be happy to review this feature.

My suggestion would be use an external library like django-select2 or django-autocomplete if you want to implement more sophisticated logic.
Please also keep in mind, the admin is not recommend to be used for sofistikated user interfaces.

Based on the packages out there targeting the admin & the extensive articles on customizing it, that recommendation just seems optimistic. Django's built-in admin is hailed as one of its selling points, and the fact that it HAS a strong built-in solution has probably discouraged the creation of third-party standalone packages targeting scaffolding & building admin backends - why reinvent the wheel? This recommendation seems to ignore reality - many folks are using the admin to build complex interfaces, the autocomplete in 2.0 *can* really help us all out, but it's a little half-baked at the moment. Baking it some more, to allow for filtering based on relation and decoupled sorting, seems like a high-value enhancement...

Please not that these 3rd party librarie have been around a lot longer than the new admin feature – no wheel reinvention happening. Furthermore they address a lot more use cases they are meant for user interaction (none-admins).
It's a pretty big hypophysis that "many folks are using the admin to build complex interfaces", even though this is discouraged. In general I would kindly ask you to watch your tone. This feature is a result of a lot of hard work by "many folks". Phrases like "half-baked" may hurt people's feelings.

You have to chose here, you either: Love it, change it or leave it.

comment:9 Changed 2 months ago by Carlton Gibson

Hi. Just seconding Joe's comment about tone.

Can we please make sure we breathe before posting and are respectful of each other and the thought, time and energy that goes into work on Django from all the volunteers.

Thank you.

comment:10 in reply to:  8 Changed 2 months ago by David W. Lloyd

Replying to Johannes Hoppe:

Replying to Johannes Hoppe:

  • the new autocomplete widget ignores any filtering done in the "limit_choices_to" ORM definition, unlike a regular select field; not very DRY, since limit_choices_to can, with other widgets, be used to filter lookups effectively... inconsistent, unintuitive behavior. If you're not going to fix it, perhaps update the autocomplete documentation to mention that limit_choices_to is completely ignored...

I agree this is a problem. I would much welcome a fix here to. It seems we all missed in the reviews.

I think the problem is that any fix would almost have to do what the feature request here is proposing - if the view doesn't know where the relation is coming from, it can't consult the ORM field and get the correct limit_choices_to filter to apply. If the referring model were passed in, one way or another, this filtering could be accomplished. Rather than doing a view per widget, having the ModelAdmin provide its underlying model to any autocomplete view being referenced seems like it might do the trick?

Go ahead an decouple it. That's an easy one. You add a new method that by defaults calls the current soring method.
Please open a separate issue for that one. I would be happy to review this feature.

Will do, thanks!

It's a pretty big hypophysis that "many folks are using the admin to build complex interfaces", even though this is discouraged. In general I would kindly ask you to watch your tone. This feature is a result of a lot of hard work by "many folks". Phrases like "half-baked" may hurt people's feelings.

You have to chose here, you either: Love it, change it or leave it.

Understood; I'm new here and this wasn't the right tone, I apologize. I do love 95% of it and I hope I can help change the other five.

Regarding my hypothesis, though, some of the most starred/popular django-related projects on github are extensions/enhancements to the admin, making it more sophisticated:

I believe this supports a hypothesis that a good number of users find the admin powerful but also wish to enhance its capabilities and add sophistication.

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

comment:11 Changed 2 months ago by Carlton Gibson

Is this really a Someday/Maybe, rather than a wontfix as it stands?
No doubt we evolve the capabilities here but this doesn't look at all actionable with the current design.

As per comment on #29700, I'd (currently/initially) favour pointing users to subclassing AutocompleteJsonView and seeing what they come up with.
I suspect good ideas would come out of there...

comment:12 Changed 2 months ago by Johannes Hoppe

Is there a ticket now for the limit_choices_to issue yet? I'd really like to fix that one.

comment:13 in reply to:  12 Changed 2 months ago by David W. Lloyd

Replying to Johannes Hoppe:

Is there a ticket now for the limit_choices_to issue yet? I'd really like to fix that one.

I can create a ticket, but isn't it the same problem as this ticket? Once the AutocompleteView knows which model to get "limit_choices_to" from, the original issue being presented here would *also* be addressed at the same time - unless I'm missing something?

I'll gladly create a separate ticket for limit_choices_to if you prefer, I just thought that the solution to that problem would end up fixing this issue as well...

comment:14 Changed 2 months ago by Johannes Hoppe

Well not necessarily. I did have a go at this yesterday evening. limit_choices_to could be fixed, without a larger refactoring.
I would use a couple of strange API's though. I am not yet happy with my solution.

comment:15 in reply to:  14 Changed 2 months ago by David W. Lloyd

Replying to Johannes Hoppe:

Well not necessarily. I did have a go at this yesterday evening. limit_choices_to could be fixed, without a larger refactoring.
I would use a couple of strange API's though. I am not yet happy with my solution.

I'm curious how limit_choices_to can be accessed without also then knowing the referring model... so I'll log the ticket and link this one :)

Note: See TracTickets for help on using tickets.
Back to Top