Getting Started
Out of the box, django-seeker supports building a filter-based search interface driven from a django model. To get started, we'll walk through adding a search interface for a model to an existing project. Keep in mind that the backend is pluggable, allowing you to write code to search on any data model.
Prerequisites
- jQuery
- json2.js
- jQuery UI Datepicker
- jQuery Form Plugin (for AJAX file imports)
URLs
Including the seeker application is easy:
from seeker.plugins.model import ModelSearchPlugin
params = {
'plugin': ModelSearchPlugin(MyModel),
'base_template': 'search.html',
}
urlpatterns = patterns('',
( r'^search/', include('seeker.urls'), params ),
...
)The base_template parameter is the name of a template that the seeker template will derive from. By default, it looks for a template named search.html. This allows you to embed the search interface into your site using your own base template. The base template can also take care of including the required CSS and javascript files.
There is also a media_url parameter to specify the location of the images that seeker needs to load. By default, media_url defaults to settings.MEDIA_URL + '/images/seeker/', so if your MEDIA_URL was set to http://media.mysite.com, media_url would be http://media.mysite.com/images/seeker/. We'll get into media more below.
Media
Seeker relies on some external javascript libraries, as well as it's own javascript code. As mentioned before, including these files in a base template makes things very easy. Your base template (search.html in the example above) may look something like this:
{% extends "site_base.html" %}
{% block extra_head %}
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/seeker.css" />
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/ui.datepicker.css" />
<script type="text/javascript" src="{{ MEDIA_URL }}js/json2.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery.form.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/ui.datepicker.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/seeker.util.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/seeker.filter.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/seeker.results.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/seeker.init.js"></script>
{% endblock %}
{% block content %}
{% block seeker %}
{% endblock %}
{% endblock %}In this template, jquery.js was not included, since it was already included as part of the site_base.html template. You'll notice that we override the content block, and set up a seeker block -- this is where the interface will be rendered. This template also assumes that you have either copied or symlinked the necessary files into the appropriate MEDIA_ROOT directories. Basically, as long as all the required files are included, seeker doesn't care how you get them there.
Customization
The interface is fully customizable using CSS. You can also customize the HTML by using your own template, and passing template_name as a parameter when you include the URL configuration.
As of r7, you can create an inner Search class (much like Meta) to define excluded fields, initially displayed fields, and follow relationships. For example:
class OtherModel (models.Model):
data1 = models.CharField( max_length=100 )
data2 = models.CharField( max_length=100 )
class MyModel (models.Model):
label = models.CharField( max_length=100 )
status = models.ForeignKey( Status )
active = models.BooleanField()
other_info = models.ForeignKey( OtherModel )
class Search:
exclude = ('active','other_info__data2')
initial = ('label','status','other_info__data1')
follow = ('other_info',)Note that you can exclude related fields from being searched/displayed, as well as specifying related fields to be initially displayed. The follow argument tells ModelSearchPlugin that fields from the related model should also be included for search/display. If the followed model has a Search inner class, those rules as respected as well.
Caching and Performance
By default, the ModelSearchPlugin uses Django's cache system to cache result sets. This is controllable by the cache_results and cache_time properties on the plugin object.
As of r7, the ModelSearchPlugin takes an optional select_depth argument, which defaults to 1. This is passed as the depth argument to select_related(). Ideally, it should be set to the maximum depth of any related fields that are available as display fields. This will greatly improve performance when rendering and sorting result sets.