full text search

This commit is contained in:
Miguel Grinberg 2012-12-16 00:35:16 -08:00
parent 1886654ff9
commit 8a27076ae4
6 changed files with 42 additions and 4 deletions

View File

@ -28,3 +28,5 @@ class EditForm(Form):
class PostForm(Form):
post = TextField('post', validators = [Required()])
class SearchForm(Form):
search = TextField('search', validators = [Required()])

View File

@ -1,5 +1,7 @@
from hashlib import md5
from app import db
from app import app
import flask.ext.whooshalchemy as whooshalchemy
ROLE_USER = 0
ROLE_ADMIN = 1
@ -71,10 +73,14 @@ class User(db.Model):
return '<User %r>' % (self.nickname)
class Post(db.Model):
__searchable__ = ['body']
id = db.Column(db.Integer, primary_key = True)
body = db.Column(db.String(140))
timestamp = db.Column(db.DateTime)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
def __repr__(self):
return '<Post %r>' % (self.text)
return '<Post %r>' % (self.body)
whooshalchemy.whoosh_index(app, Post)

View File

@ -11,6 +11,7 @@
<a href="{{ url_for('index') }}">Home</a>
{% if g.user.is_authenticated() %}
| <a href="{{ url_for('user', nickname = g.user.nickname) }}">Your Profile</a>
| <form style="display: inline;" action="{{url_for('search')}}" method="post" name="search">{{g.search_form.hidden_tag()}}{{g.search_form.search(size=20)}}<input type="submit" value="Search"></form>
| <a href="{{ url_for('logout') }}">Logout</a>
{% endif %}
</div>

View File

@ -0,0 +1,9 @@
<!-- extend base layout -->
{% extends "base.html" %}
{% block content %}
<h1>Search results for "{{query}}":</h1>
{% for post in results %}
{% include 'post.html' %}
{% endfor %}
{% endblock %}

View File

@ -1,10 +1,10 @@
from flask import render_template, flash, redirect, session, url_for, request, g
from flask.ext.login import login_user, logout_user, current_user, login_required
from app import app, db, lm, oid
from forms import LoginForm, EditForm, PostForm
from forms import LoginForm, EditForm, PostForm, SearchForm
from models import User, ROLE_USER, ROLE_ADMIN, Post
from datetime import datetime
from config import POSTS_PER_PAGE
from config import POSTS_PER_PAGE, MAX_SEARCH_RESULTS
@lm.user_loader
def load_user(id):
@ -17,6 +17,7 @@ def before_request():
g.user.last_seen = datetime.utcnow()
db.session.add(g.user)
db.session.commit()
g.search_form = SearchForm()
@app.errorhandler(404)
def internal_error(error):
@ -118,6 +119,7 @@ def edit():
form = form)
@app.route('/follow/<nickname>')
@login_required
def follow(nickname):
user = User.query.filter_by(nickname = nickname).first()
if user == None:
@ -136,6 +138,7 @@ def follow(nickname):
return redirect(url_for('user', nickname = nickname))
@app.route('/unfollow/<nickname>')
@login_required
def unfollow(nickname):
user = User.query.filter_by(nickname = nickname).first()
if user == None:
@ -152,3 +155,19 @@ def unfollow(nickname):
db.session.commit()
flash('You have stopped following ' + nickname + '.')
return redirect(url_for('user', nickname = nickname))
@app.route('/search', methods = ['POST'])
@login_required
def search():
if not g.search_form.validate_on_submit():
return redirect(url_for('index'))
return redirect(url_for('search_results', query = g.search_form.search.data))
@app.route('/search_results/<query>')
@login_required
def search_results(query):
results = Post.query.whoosh_search(query, MAX_SEARCH_RESULTS).all()
return render_template('search_results.html',
query = query,
results = results)

View File

@ -13,6 +13,7 @@ OPENID_PROVIDERS = [
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.db')
SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')
WHOOSH_BASE = os.path.join(basedir, 'search.db')
# mail server settings
MAIL_SERVER = 'localhost'
@ -25,4 +26,4 @@ ADMINS = ['you@example.com']
# pagination
POSTS_PER_PAGE = 3
MAX_SEARCH_RESULTS = 50