Created
May 11, 2013 20:54
-
-
Save georgefs/5561397 to your computer and use it in GitHub Desktop.
django advance search form
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment