This django form class creates a search form for a model and generates a query from the submitted data.
To use, extend the BaseSearchForm class, defining a Meta class with the following values:
base_qs is the queryset to search, ie. MyModel.objectssearch_fields are the fields to search, using the same syntax as the django admin
directive of the same name, ie.
'fieldname' - field must contain the search string'^fieldname' - field must start with the search string'=fieldname' - field must exactly equal the search string'@fieldname' - performs a fulltext search (mysql/postgres only) on fieldRelated model fields can also be searched, ie 'mycategory__name' will search
the name field on the mycategory model.
Custom fields can also be added to filter the results - by default, these perform
an exact-match search on the model field of the same name. A prepare_FIELDNAME
method can be defined for each custom field for advanced queries - this method
should return a Q instance for addition to the overall query.
from django.db.models import Q
from simple_search import BaseSearchForm
from myapp.models import MyModel, MyCategory
class MyModelSearchForm(BaseSearchForm):
class Meta:
base_qs = MyModel.objects
search_fields = ('^name', 'description', '=id')
"""
A custom addition - the absence of a prepare_category method means
the query will search for an exact match on this field.
"""
category = forms.ModelChoiceField(
queryset = MyCategory.objects.all(),
required = False
)
"""
This field creates a custom query addition via the prepare_start_date
method.
"""
start_date = forms.DateField(
required = False,
input_formats = ('%Y-%m-%d',),
)
def prepare_start_date(self):
if self.cleaned_data['start_date']:
return Q(creation_date__gte=self.cleaned_data['start_date'])
else:
return ""
from django.shortcuts import render_to_response
from django.template import RequestContext
from myapp.forms import MyModelSearchForm
def search(request):
if request.GET:
form = MyModelSearchForm(request.GET)
if form.is_valid():
results = form.get_result_queryset()
else:
results = []
else:
form = MyModelSearchForm()
results = []
return render_to_response(
'search.html',
RequestContext(request, {
'form': form,
'results': results,
})
)
You can try it out on this site, either from the search box in the footer or here.