Simple Django Search

(Original django-users message)

I’ve been interested in a search feature in Django for some time now. I did some research lately and found the following posts about it:

I’ve found that all of those solutions require some additional software (such as Lucene, for instance). I was thinking about something that would be pure Django/Python code, that would work like django.contrib.comments.

I’ve recently written the simplest code I could, to do the job: index objects and then allow to search them, returning their titles and absolute URLs. I’ve tried to make it as general as possible. My implementation is inspired (or stolen from ;-) ) django.contrib.comments. It can index any class of objects. Classes to be indexed need to implement two methods: get_search_text() and get_absolute_url()

For instance, if we have a class Band with URLs like: http://www.myserver.com/bands/earth-wind-and-fire/, the corresponding methods will look like this:

class Band(models.Model):
    name = models.CharField(maxlength = 250)
    slug = models.SlugField(maxlength = 250, prepopulate_from = ('name',))
    about_band = models.TextField()
    def get_search_text(self):
        return self.name + " " + self.about_band
    def get_absolute_url(self):
        return "/bands/%s/" % self.slug

Here’s an example code for indexing objects:

from myapp.models import MyClass
from django.contrib.search.models import Keyword
from django.contrib.contenttypes.models import ContentType

ct = ContentType.objects.get_for_model(MyClass)
object_id = 1
Keyword.objects.index_object(ct, object_id)

...and for searching:

from django.contrib.search.models import KeywordManager
from django.contrib.contenttypes.models import ContentType
from myapp.models import MyClass
ct = ContentType.objects.get_for_model(MyClass)
km = KeywordManager()
result = km.search(ct, "Monty Python")
print result

[{'url': '/path/object/',
 'preview': 'preview of the object content',
 'title': 'Object title' },
 { ... }, ... ]

Results are a list of dictionaries where each dictionary has fields: url, preview and title.

The code is available from:

This is very immature code which I’ve put together last few days, but it does the job and I think it could be useful for other people too.

It’s biggest strength is that it’s enough to put few files into the django/contrib directory and run syncdb—it’s ready to go.

All comments are very welcome!

Maciej Bliziński

Last modified on Sun Jul 01 08:39:23 +0100 2007.