Skip to content
strig edited this page Apr 19, 2015 · 4 revisions

Searching for models with django-watson

Once you have registered your models with django-watson, searching for them is as easy as:

search_results = watson.search("Your search terms")

You can then iterate over the search results in your views:

for result in search_results:
    print result.title, result.url

Or in your templates:

<ul>
    {% for result in search_results %}
        <li>
            <article>
                <h1>
                    {% if result.url %}<a href="{{result.url}}">{% endif %}
                    {{result.title}}
                    {% if result.url %}</a>{% endif %}
                </h1>
                {% if result.description %}
                    <p>{{result.description}}</p>
                {% endif %}
            </article>
        </li>
    {% endfor %}
</ul>

Displaying additional information in your search results

You can display additional information in your search results by accessing the referenced model:

for result in search_results:
    print result.object.thumbnail.url

However, looking up the model for each row of your search results can create a lot of extra database queries. If you want to speed up your search rendering, you can store additional fields in your search entries when you register them, and access them via the meta propery of the search result:

for result in search_results:
    print result.meta["thumbnail_url"]

For more information about storing addional information in your search results, please visit the registering models wiki page.

Searching for a subset of your registered models

Sometimes you don't want to search all of your registered models - just a subset of them. This is easily acheived using the models and exclude parameters:

watson.search("Search terms", models=(YourModel,))
watson.search("Search terms", exclude=(YourOtherModel,))

You can even specify a subset of model instances to search by specifying a QuerySet:

watson.search("Search terms", models=(YourModel.objects.filter(title="foo"),))
watson.search("Search terms", exclude=(YourOtherModel.objects.filter(title="bar"),))

Searching for only one type of model

Sometimes you only want to search one class of model, and would like to return a queryset of that model rather than a list of generic search results. To perform a full text search on just one class of model, use the watson.filter() method:

for obj in watson.filter(YourModel, "Search term"):
    print obj.title, obj.thumbnail  # These are actual instances of `YourModel`, rather than `SearchEntry`.

Alternatively, you can pass in a queryset to search though:

your_queryset = YourModel.objects.filter(title="foo")
your_new_queryset = watson.filter(your_queryset, "Search term")

Search results with ranking

Both the watson.search() and watson.filter() methods return results that are ranked by relevance. This is generally fantastic, as it provides the best search results for your users.

However, if you're going to order the results by another field, or aren't interested in the ranking, then you can speed up the search by turning ranking off.

watson.search("Search terms", ranking=False)
watson.filter(YourModel, "Search terms", ranking=False)