Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added initial Haystack integration.

I'm using a throwaway object (Document) since it's the path of least resistance
to getting search working. The basic idea I'm following here is the one Eric
Holscher developed for Read The Docs -- see
http://ericholscher.com/blog/2010/nov/17/using-haystack-index-non-database-content/.
  • Loading branch information...
commit aaa0a6ed1abcb5688c4ecd24cc502441d46357df 1 parent 65e227a
@jacobian jacobian authored
View
1  deploy-requirements.txt
@@ -2,6 +2,7 @@
akismet == 0.2.0
Django >= 1.2, < 1.3
+django-haystack == 1.1.0
django-registration == 0.7
docutils >= 0.6, < 0.7
FeedParser >= 4.1, < 5.0
View
41 django_website/docs/migrations/0001_initial.py
@@ -0,0 +1,41 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Adding model 'DocumentRelease'
+ db.create_table('docs_documentrelease', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('lang', self.gf('django.db.models.fields.CharField')(default='en', max_length=2)),
+ ('version', self.gf('django.db.models.fields.CharField')(max_length=20)),
+ ('scm', self.gf('django.db.models.fields.CharField')(max_length=10)),
+ ('scm_url', self.gf('django.db.models.fields.URLField')(max_length=200)),
+ ('is_default', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ))
+ db.send_create_signal('docs', ['DocumentRelease'])
+
+
+ def backwards(self, orm):
+
+ # Deleting model 'DocumentRelease'
+ db.delete_table('docs_documentrelease')
+
+
+ models = {
+ 'docs.documentrelease': {
+ 'Meta': {'object_name': 'DocumentRelease'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_default': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'lang': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '2'}),
+ 'scm': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
+ 'scm_url': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
+ 'version': ('django.db.models.fields.CharField', [], {'max_length': '20'})
+ }
+ }
+
+ complete_apps = ['docs']
View
48 django_website/docs/migrations/0002_add_document_model.py
@@ -0,0 +1,48 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Adding model 'Document'
+ db.create_table('docs_document', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('release', self.gf('django.db.models.fields.related.ForeignKey')(related_name='documents', to=orm['docs.DocumentRelease'])),
+ ('path', self.gf('django.db.models.fields.CharField')(max_length=500)),
+ ('title', self.gf('django.db.models.fields.CharField')(max_length=500)),
+ ('content', self.gf('django.db.models.fields.TextField')()),
+ ))
+ db.send_create_signal('docs', ['Document'])
+
+
+ def backwards(self, orm):
+
+ # Deleting model 'Document'
+ db.delete_table('docs_document')
+
+
+ models = {
+ 'docs.document': {
+ 'Meta': {'object_name': 'Document'},
+ 'content': ('django.db.models.fields.TextField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'path': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
+ 'release': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'documents'", 'to': "orm['docs.DocumentRelease']"}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '500'})
+ },
+ 'docs.documentrelease': {
+ 'Meta': {'object_name': 'DocumentRelease'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_default': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'lang': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '2'}),
+ 'scm': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
+ 'scm_url': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
+ 'version': ('django.db.models.fields.CharField', [], {'max_length': '20'})
+ }
+ }
+
+ complete_apps = ['docs']
View
0  django_website/docs/migrations/__init__.py
No changes.
View
19 django_website/docs/models.py
@@ -35,3 +35,22 @@ def save(self, *args, **kwargs):
DocumentRelease.objects.update(is_default=False)
super(DocumentRelease, self).save(*args, **kwargs)
+class Document(models.Model):
+ """
+ An individual document. Used mainly as a hook point for Haystack.
+ """
+ release = models.ForeignKey(DocumentRelease, related_name='documents')
+ path = models.CharField(max_length=500)
+ title = models.TextField(max_length=500)
+ content = models.TextField()
+
+ def __unicode__(self):
+ return "/".join([self.release.lang, self.release.version, self.path])
+
+ @models.permalink
+ def get_absolute_url(self):
+ return (
+ 'document-detail',
+ [],
+ {'lang': self.lang, 'version': self.version, 'url': self.path}
+ )
View
25 django_website/docs/search_indexes.py
@@ -0,0 +1,25 @@
+import json
+from django.conf import settings
+import haystack
+import haystack.indexes
+from . import utils
+from .models import Document
+
+class DocumentIndex(haystack.indexes.SearchIndex):
+ text = haystack.indexes.CharField(document=True)
+ lang = haystack.indexes.CharField(model_attr='release__lang', faceted=True)
+ version = haystack.indexes.CharField(model_attr='release__version', faceted=True)
+ path = haystack.indexes.CharField(model_attr='path')
+ title = haystack.indexes.CharField(model_attr='title')
+
+ def get_queryset(self):
+ return Document.objects.all().select_related('release')
+
+ def prepare_text(self, obj):
+ root = utils.get_doc_root(obj.release.lang, obj.release.version)
+ docpath = utils.get_doc_path(root, obj.path)
+ with open(docpath) as fp:
+ doc = json.load(fp)
+ return doc['body']
+
+haystack.site.register(Document, DocumentIndex)
View
1  django_website/docs/search_sites.py
@@ -0,0 +1 @@
+import haystack; haystack.autodiscover()
View
14 django_website/settings/docs.py
@@ -2,7 +2,10 @@
PREPEND_WWW = False
APPEND_SLASH = True
-INSTALLED_APPS = ['django_website.docs']
+INSTALLED_APPS = [
+ 'django_website.docs',
+ 'haystack',
+]
TEMPLATE_CONTEXT_PROCESSORS += ["django.core.context_processors.request"]
ROOT_URLCONF = 'django_website.urls.docs'
CACHE_MIDDLEWARE_KEY_PREFIX = 'djangodocs'
@@ -12,3 +15,12 @@
DOCS_BUILD_ROOT = BASE.ancestor(2).child('docbuilds')
else:
DOCS_BUILD_ROOT = '/tmp/djangodocs'
+
+# Haystack settings
+HAYSTACK_SITECONF = 'django_website.docs.search_sites'
+if PRODUCTION:
+ HAYSTACK_SEARCH_ENGINE = 'solr'
+ HAYSTACK_SOLR_URL = 'http://127.0.0.1:8983/solr'
+else:
+ HAYSTACK_SEARCH_ENGINE = 'whoosh'
+ HAYSTACK_WHOOSH_PATH = '/tmp/djangodocs.index'
Please sign in to comment.
Something went wrong with that request. Please try again.