﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
26184	Allow using custom lookups and transforms in ModelAdmin.search_fields	Bertrand Bordage	Krzysztof Nazarewski	"When you define a `ModelAdmin` like this:
{{{#!python
class MyAdmin(ModelAdmin):
    search_fields = ['my_field__unaccent']
}}}
a `FieldDoesNotExist` is raised when you try to search something.

This is because the admin fails to identify `__unaccent` as a valid lookup because `django.contrib.admin.utils.lookup_needs_distinct` relies on two kludges:
- it assumes that the last part of the lookup expression is always a lookup (`iexact`, `icontains`, `search`, etc), and that all other parts are fields. In the unaccent scenario, the penultimate part is a transform since the admin generates this expression: `myfield__unaccent__icontains`
- it only checks that lookups are in `django.db.models.sql.constants.QUERY_TERMS`. But **`QUERY_TERMS` is no longer used and should be removed**, it only contains ""classic"" lookups

The solution is to use [https://docs.djangoproject.com/en/1.9/ref/models/lookups/#registration-api the new registration API] instead, with the `get_lookup` and `get_transform` methods.

A better solution would be to make `search_fields` more consistent with the rest of Django by removing the `^`, `=`, & `@` shortcuts. If not, providing them on the whole ORM would be consistent. In my opinion, they should be removed, they complicate Django while limiting its possibilities (what if someone wants `exact` instead of `iexact`?). If someone has a lot of fields with the same transforms/lookups, this can be done:
{{{#!python
class BookAdmin(ModelAdmin):
    search_fields = ('title', 'subtitle', 'author_first_name', 'author_last_name', 'publisher')
    search_fields = [le + '__unaccent__icontains' for le in search_fields]
}}}
or even this if you need it often:
{{{#!python
class SearchMixin:
    def get_search_fields(self, request):
        return [le + '__unaccent__icontains' for le in self.search_fields]

class BookAdmin(SearchMixin, ModelAdmin):
    search_fields = ('title', 'subtitle', 'author_first_name', 'author_last_name', 'publisher')
}}}

I’m working on an implementation for one of my projects, I’ll submit it when done."	New feature	closed	contrib.admin	dev	Normal	fixed		berker.peksag@… camilo.nova@…	Accepted	1	0	0	0	0	0
