Added search app

This commit is contained in:
Roberto Rosario
2011-02-03 22:52:25 -04:00
parent 5854a1ce50
commit 327a00ede6
15 changed files with 250 additions and 1 deletions

View File

@@ -6,6 +6,8 @@ from datetime import datetime
from django.db import models
from django.utils.translation import ugettext_lazy as _
from dynamic_search.api import register
from documents.conf.settings import AVAILABLE_FUNCTIONS
@@ -50,7 +52,6 @@ class Document(models.Model):
@models.permalink
def get_absolute_url(self):
return ('document_view', [self.id])
available_functions_string = (_(u' Available functions: %s') % ','.join(['%s()' % name for name, function in AVAILABLE_FUNCTIONS.items()])) if AVAILABLE_FUNCTIONS else ''
@@ -96,3 +97,6 @@ class DocumentMetadata(models.Model):
class Meta:
verbose_name = _(u'document metadata')
verbose_name_plural = _(u'document metadata')
register(Document, _(u'document'), ['document_type__name', 'file_mimetype', 'file_filename', 'file_extension'])

View File

@@ -0,0 +1,6 @@
from django.utils.translation import ugettext_lazy as _
from common.api import register_menu
register_menu([
{'text':_(u'search'), 'view':'search', 'famfam':'zoom', 'position':5},
])

View File

@@ -0,0 +1,7 @@
search_list = {}
def register(model, text, field_list):
if model in search_list:
search_list[model]['fields'].append(field_list)
else:
search_list[model] = {'fields':field_list, 'text':text}

View File

@@ -0,0 +1,7 @@
from django import forms
from django.utils.translation import ugettext_lazy as _
class SearchForm(forms.Form):
q = forms.CharField(max_length=128, label=_(u'Search term'))

Binary file not shown.

View File

@@ -0,0 +1,45 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-02-03 01:11-0400\n"
"PO-Revision-Date: 2011-01-28 09:28\n"
"Last-Translator: <admin@admin.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Translated-Using: django-rosetta 0.5.6\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: __init__.py:5
msgid "search"
msgstr "búsqueda"
#: forms.py:6
msgid "Search term"
msgstr "Término de búsqueda"
#: views.py:77
msgid "Search"
msgstr "Búsqueda"
#: views.py:78
msgid "type"
msgstr "tipo"
#: views.py:79
#, python-format
msgid "results with: %s"
msgstr "resultados con: %s"
#: templates/search_results.html:14
msgid "No results found"
msgstr "No hay resultados"

Binary file not shown.

View File

@@ -0,0 +1,45 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-02-03 01:31-0400\n"
"PO-Revision-Date: 2011-02-03 01:31\n"
"Last-Translator: <admin@admin.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: \n"
"X-Translated-Using: django-rosetta 0.5.6\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
#: __init__.py:5
msgid "search"
msgstr "поиск"
#: forms.py:6
msgid "Search term"
msgstr "Поиск по критериям"
#: views.py:77
msgid "Search"
msgstr "Поиск"
#: views.py:78
msgid "type"
msgstr "типа"
#: views.py:79
#, python-format
msgid "results with: %s"
msgstr "результаты: %s"
#: templates/search_results.html:14
msgid "No results found"
msgstr "Ничего не наидено"

View File

@@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

View File

@@ -0,0 +1,18 @@
{% extends "base.html" %}
{% load i18n %}
{% block title %} :: {% trans 'Search results' %}{% endblock %}
{% block content %}
{% with 'get' as submit_method %}
{% with form_title as title %}
{% include 'generic_form_subtemplate.html' %}
{% endwith %}
{% endwith %}
{% if query_string %}
{% include 'generic_list_subtemplate.html' %}
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,23 @@
"""
This file demonstrates two different styles of tests (one doctest and one
unittest). These will both pass when you run "manage.py test".
Replace these with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.failUnlessEqual(1 + 1, 2)
__test__ = {"doctest": """
Another way to test that 1 + 1 is equal to 2.
>>> 1 + 1 == 2
True
"""}

View File

@@ -0,0 +1,8 @@
from django.conf.urls.defaults import *
urlpatterns = patterns('dynamic_search.views',
url(r'^search/$', 'search', (), 'search'),
)

View File

@@ -0,0 +1,81 @@
import re
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.utils.translation import ugettext as _
from django.db.models import Q
from api import search_list
from forms import SearchForm
#original code from:
#http://www.julienphalip.com/blog/2008/08/16/adding-search-django-site-snap/
def normalize_query(query_string,
findterms=re.compile(r'"([^"]+)"|(\S+)').findall,
normspace=re.compile(r'\s{2,}').sub):
''' Splits the query string in invidual keywords, getting rid of unecessary spaces
and grouping quoted words together.
Example:
>>> normalize_query(' some random words "with quotes " and spaces')
['some', 'random', 'words', 'with quotes', 'and', 'spaces']
'''
return [normspace(' ', (t[0] or t[1]).strip()) for t in findterms(query_string)]
def get_query(terms, search_fields):
''' Returns a query, that is a combination of Q objects. That combination
aims to search keywords within a model by testing the given search fields.
'''
query = None # Query to search for every search term
#terms = normalize_query(query_string)
for term in terms:
or_query = None # Query to search for a given term in each field
for field_name in search_fields:
q = Q(**{"%s__icontains" % field_name: term})
if or_query is None:
or_query = q
else:
or_query = or_query | q
if query is None:
query = or_query
else:
query = query & or_query
return query
def search(request):
query_string = ''
found_entries = {}
object_list = []
if ('q' in request.GET) and request.GET['q'].strip():
query_string = request.GET['q']
form = SearchForm(initial={'q':query_string})
terms = normalize_query(query_string)
for model, data in search_list.items():
query = get_query(terms, data['fields'])
results = model.objects.filter(query)
if results:
found_entries[data['text']] = results
for result in results:
object_list.append(result)
else:
form = SearchForm()
return render_to_response('search_results.html', {
'query_string':query_string,
'found_entries':found_entries,
'form':form,
'object_list':object_list,
'form_title':_(u'Search'),
'extra_columns':[{'name':_(u'type'), 'attribute':lambda x:x._meta.verbose_name[0].upper() + x._meta.verbose_name[1:]}],
'title':_(u'results with: %s') % query_string
},
context_instance=RequestContext(request))

View File

@@ -121,6 +121,7 @@ INSTALLED_APPS = (
'common',
'documents',
'pagination',
'dynamic_search',
)
TEMPLATE_CONTEXT_PROCESSORS = (

View File

@@ -8,6 +8,7 @@ urlpatterns = patterns('',
(r'^', include('common.urls')),
(r'^', include('main.urls')),
(r'^documents/', include('documents.urls')),
(r'^search/', include('dynamic_search.urls')),
(r'^admin/doc/', include('django.contrib.admindocs.urls')),
(r'^admin/', include(admin.site.urls)),
)