You have a dozen of views for listing Model objects. One day your client wants to
add search into every page which are listing objects. Nightmare!! I had a couple of views like this
which lists the objects in a table. I was happy with what provided by the
django’s generic ListView. I just had to inherit from it and define the model and
template. So i didn’t want to give away this comfort. I just wanted the the same function,
with search enabled on certain fields defined. This is where we can make use of the real
power of django’s class based views. There is a method get_queryset in
ListView which returns the list of all objects in the given model. By
overriding this method, instead of returning all objects we can do the
filtering based on the search term passed as get parameter and return the subset.
The rest will work as it is :)
This view depends on the get_query method by Julien Phalip.
On providing the search term and the fields to search it will return a
combination of Q objects which can be passed to Queryset’s filter method for
filtering it.
Now you can extend ListSearchView instead of generic ListView to support search in
your views like this.
ListSearchView also injects the search term into the context data. So in
template you can check if query_string exists and add messages like the
following.
You can add search box like the following, So when the user is searching,
the search term will be filled in the textbox, If there is no search term
it will show the placeholder ‘Search’.
The same can be achieved by constructing a Mixin from this and using it with
the ListView in your existing views. But I prefer overriding ListView and
using ListSearchView.