I am running Django 1.10, 1.11 and r_black the solution did not fit completely, since Django was complaining that the filter fields should inherit from "FieldListFilter".
So, a simple change for the filter inherited from FieldListFilter took care of Django's salary and did not require specifying a new class for each field at the same time.
class SingleTextInputFilter(admin.FieldListFilter): """ renders filter form with text input and submit button """ parameter_name = None template = "admin/textinput_filter.html" def __init__(self, field, request, params, model, model_admin, field_path): super().__init__(field, request, params, model, model_admin, field_path) if self.parameter_name is None: self.parameter_name = self.field.name if self.parameter_name in params: value = params.pop(self.parameter_name) self.used_parameters[self.parameter_name] = value def queryset(self, request, queryset): if self.value(): return queryset.filter(imei__icontains=self.value()) def value(self): """ Returns the value (in string format) provided in the request's query string for this filter, if any. If the value wasn't provided then returns None. """ return self.used_parameters.get(self.parameter_name, None) def has_output(self): return True def expected_parameters(self): """ Returns the list of parameter names that are expected from the request query string and that will be used by this filter. """ return [self.parameter_name] def choices(self, cl): all_choice = { 'selected': self.value() is None, 'query_string': cl.get_query_string({}, [self.parameter_name]), 'display': _('All'), } return ({ 'get_query': cl.params, 'current_value': self.value(), 'all_choice': all_choice, 'parameter_name': self.parameter_name }, )
templates / admin / textinput_filter.html (no change):
{% load i18n %} <h3>{% blocktrans with filter_title=title %} By {{ filter_title }} {% endblocktrans %}</h3> {#i for item, to be short in names#} {% with choices.0 as i %} <ul> <li> <form method="get"> <input type="search" name="{{ i.parameter_name }}" value="{{ i.current_value|default_if_none:"" }}"/> {#create hidden inputs to preserve values from other filters and search field#} {% for k, v in i.get_query.items %} {% if not k == i.parameter_name %} <input type="hidden" name="{{ k }}" value="{{ v }}"> {% endif %} {% endfor %} <input type="submit" value="{% trans 'apply' %}"> </form> </li> {#show "All" link to reset current filter#} <li{% if i.all_choice.selected %} class="selected"{% endif %}> <a href="{{ i.all_choice.query_string|iriencode }}"> {{ i.all_choice.display }} </a> </li> </ul> {% endwith %}
Using:
class MyAdmin(admin.ModelAdmin): list_display = [your fields] list_filter = [('field 1', SingleTextInputFilter), ('field 2', SingleTextInputFilter), further fields]