class FormForAdvancedSearch(forms.Form): #you can put any field here this is an example so only 1 simple CharField form_field1 = forms.CharField() class MyModelAdmin(admin.ModelAdmin): # the auxiliary search form advanced_search_form = FormForAdvancedSearch() # a dictionary of key that will be removed from the GET QueryDict # this is necessary otherwise ChangeList will complain for malformed # query string other_search_fields={} # standard search search_fields = ['field1','field2'] def lookup_allowed(self, lookup): if lookup in self.advanced_search_form.fields.keys(): return True return super(MyModelAdmin, self).lookup_allowed(lookup) def queryset(self, request): qs = super(MyModelAdmin, self).queryset(request) # probably there is a better way to extract this value this is just # an example and depends on the type of the form field form_field1_value = search_fields.get("form_field1",[""])[0] qs.filter(field3__icontains==form_field1_value) return qs def changelist_view(self, request, extra_context=None, **kwargs): # we need to reset on every request otherwise it will survive and we # don't want that self.other_search_fields = {} extra_context = {'asf':self.advanced_search_form} # we now need to remove the elements coming from the form # and save in the other_search_fields dict but it's not allowed # to do that in place so we need to temporary enable mutability ( I don't think # it will cause any complicance but maybe someone more exeprienced on how # QueryDict works could explain it better) request.GET._mutable=True for key in asf.fields.keys(): try: temp = request.GET.pop(key) except KeyError: pass # there is no field of the form in the dict so we don't remove it else: if temp!=['']: #there is a field but it's empty so it's useless self.other_search_fields[key] = temp request.GET_mutable=False return super(MyModelAdmin, self)\ .changelist_view(request, extra_context=extra_context) admin.site.register(MyModel, MyModelAdmin) # you need a templatetag to rewrite the standard search_form tag because the default # templatetag to render the search form doesn't handle context so here it is: # remember to put it inside a source file (in my case is custom_search_form.py) that # lives in project/myapp/templatetags otherwise will not be found by the template engine from django.contrib.admin.views.main import SEARCH_VAR from django.template import Library register = Library() @register.inclusion_tag('admin/search_form.html', takes_context=True) def advanced_search_form(context, cl): """ Displays a search form for searching the list. """ return { 'asf' : context.get('asf'), 'cl': cl, 'show_result_count': cl.result_count != cl.full_result_count, 'search_var': SEARCH_VAR }