Despite warning coming from django developers, I'm still using admin classes to quickly get into reverse engineering databases.
One feature is missing: searching into fields thanks to a regex.
One dirty solution I found is to overwrite get_search_results. But most of the code comes from django itself.
If anyone has a better idea ;)
**Usage:**
1. works since get_search_results is part of ModelAdmin (1.5 if I remember well)
2. Inherit your Admin class from RegexModelAdmin
3. enclose by / the field you want to regex with:
`search_fields = ['/field/', ]`
A drop-in module to allow for full-text searchable models with very little effort. Tested with PostgreSQL 8.3, but should work on earlier versions with the tsearch2 module installed.
simple search with Q object you just pass a list of fields and the search string then it will come up with a object to use in a filter. This snippet is thanks to Julien Phalip
at [julienphalip.com](http://www.julienphalip.com/blog/2008/08/16/adding-search-django-site-snap/)
Use these tags and filter when you're rolling your own search results. This is intended to be a whole templatetags module. I keep it in my apps as `templatetags/search.py`. These should not be used to perform search queries, but rather render the results.
### Basics
There are three functions, each has both a tag *and* a filter of the same name. These functions accept, at a minimum, a body of text and a list of search terms:
* **searchexcerpt**: Truncate the text so that each search term is shown, surrounded by some number of words of context.
* **highlight**: Wrap all found search terms in an HTML span that can be styled to highlight the terms.
* **hits**: Count the occurrences of the search terms in the text.
The filters provide the most basic functionality as described above, while the tags offer more options as arguments, such as case sensitivity, whole word search, and saving the results to a context variable.
### Settings
Defaults for both the tags and filters can be changed with the following settings. Note that these settings are merely a convenience for the tags, which accept these as arguments, but are necessary for changing behavior of the filters.
* `SEARCH_CONTEXT_WORDS`: Number of words to show on the left and right of each search term. Default: 10
* `SEARCH_IGNORE_CASE`: False for case sensitive, True otherwise. Default: True
* `SEARCH_WORD_BOUNDARY`: Find whole words and not strings in the middle of words. Default: False
* `SEARCH_HIGHLIGHT_CLASS`: The class to give the HTML span element when wrapping highlighted search terms. Default: "highlight"
### Examples
Suppose you have a list `flatpages` resulting from a search query, and the search terms (split into a list) are in the context variable `terms`. This will show 5 words of context around each term and highlight matches in the title:
{% for page in flatpages %}
<h3>{{ page.title|highlight:terms }}</h3>
<p>
{% searchexcerpt terms 5 %}
{{ page.content|striptags }}
{% endsearchexcerpt %}
</p>
{% endfor %}
Add highlighting to the excerpt, and use a custom span class (the two flags are for case insensitivity and respecting word boundaries):
{% highlight 1 1 "match" %}
{% searchexcerpt terms 5 1 1 %}
{{ page.content|striptags }}
{% endsearchexcerpt %}
{% endhighlight %}
Show the number of hits in the body:
<h3>{{ page.title }}
(Hits: {{ page.content|striptags|hits:terms }})
</h3>
All tags support an `as name` suffix, in which case an object will be stored in the template context with the given name; output will be suppressed. This is more efficient when you want both the excerpt and the number of hits. The stored object depends on the tag:
* **searchexcerpt**: A dictionary with keys "original" (the text searched), "excerpt" (the summarized text with search terms), and "hits" (the number of hits in the text).
* **searchcontext**: A dictionary with keys "original", "highlighted", and "hits", with obvious values.
* **hits**: Just the number of hits, nothing special.
Getting both the hits and the excerpt with "as":
{% searchexcerpt terms 3 as content %}
{{ page.content|striptags }}
{% endsearchexcerpt %}
<p>Hits: {{ content.hits }}<br>{{ content.excerpt }}</p>
### More
For more examples see [Brian Beck's Text Adventure][announcement].
[announcement]: http://blog.brianbeck.com/post/29707610
This app allows you to utilize mysql's fulltext searching over multiple models and multiple apps, letting the site search seem more intuitive, yet still allow your content to be very structured. Essentially, it creates an entire new model that associates objects to a chunk of text to search efficiently over (and index), using the contenttypes app. Simply add the post_save events to your existing models for things you want to be searched.
I was tired browsing via tag to find snippets I saw a while ago. So I created a custom search engine with Google.
To try it out go to [http://henning.cco-ev.de/django/djangosnippets.html](http://henning.cco-ev.de/django/djangosnippets.html)
Adds a filter input above a select widget that allows live-filtering on the client-side (no ajax) in Firefox.
Example:
make_fields_searchable(ModelItemForm, {
'publisher': {'set_size': 8}, 'developer': {'set_size': 8}, 'genre': {}, 'platform': {}
})
A revised version of [zeeg's Sphinx Search ORM](http://www.djangosnippets.org/snippets/231/), using my Sphinx client and adding support for Sphinx's excerpt generator. It's still missing support for search modes/order_by/filter/exclude, but it should be easy and I will add the relevant methods soon as I need them.
Usage is the same as zeeg's class, except that you can pass a field name (or tuple for related objects) to its constructor, that will be used for excerpts:
class MyModel(models.Model):
search = SphinxSearch(excerpts_field='description')
MyModel.search.query('query')
MyModel.search.query('query').count()
Returns an ordered list of the objects in your database.
An ORM model for the Sphinx full-text search engine.
See http://www.sphinxsearch.com/ for more information.
It currently supports the following:
class MyModel(models.Model):
search = SphinxSearch()
MyModel.search.query('query')
MyModel.search.query('query').order_by('@weight', '@id', 'my_attribute')
MyModel.search.query('query').filter(my_attribute=5)
MyModel.search.query('query').filter(my_other_attribute=[5, 3,4])
MyModel.search.query('query').exclude(my_attribute=5)[0:10]
MyModel.search.query('query').count()
SphinxSearch().query('hello').on_index('model_myapp model_myotherapp')
Returns an ordered list of the objects in your database.
-- Update:
New Methods:
* count()
* index_on(<str index>)
* extra(<see django>)
* all() (does nothing)
* select_related(<see django>)
* group_by(<str attribute>, <const function>[, <str sort>)
* weights(<list weights>)
**Problem**:
You search by firing POST and paginate by firing GET, so search results disappear on GET. I want to preserve searching results, so user can paginate them.
First I try to use some static class to keep search results, but this solution has bug (thanks to svetlyak). In multiuser environment other user searching got results from previous one. No @cache_control(private=True) helps so I decided to change searching schema by using GET in the first place and to supply query string on each 'paging' request. Also added some memory cache that expires after 5 min
**In template**
Please append query to each paging link:
<a href="?page={{ page_number }}
&search_query={{ query|urlencode }}">
{{ page_number }}</a>
This snippet should keep search results on pagination in multiuser environment.