79 lines
2.9 KiB
Python
79 lines
2.9 KiB
Python
"""Admin integration for django-watson."""
|
|
|
|
from __future__ import unicode_literals
|
|
|
|
from django.contrib import admin
|
|
from django.contrib.admin.views.main import ChangeList
|
|
|
|
from watson.search import SearchEngine, SearchAdapter
|
|
|
|
|
|
admin_search_engine = SearchEngine("admin")
|
|
|
|
|
|
class WatsonSearchChangeList(ChangeList):
|
|
|
|
"""A change list that takes advantage of django-watson full text search."""
|
|
|
|
def get_queryset(self, *args, **kwargs):
|
|
"""Creates the query set."""
|
|
# Do the basic searching.
|
|
search_fields = self.search_fields
|
|
self.search_fields = ()
|
|
try:
|
|
qs = super(WatsonSearchChangeList, self).get_queryset(*args, **kwargs)
|
|
finally:
|
|
self.search_fields = search_fields
|
|
# Do the full text searching.
|
|
if self.query.strip():
|
|
qs = self.model_admin.search_engine.filter(qs, self.query, ranking=False)
|
|
return qs
|
|
|
|
|
|
class SearchAdmin(admin.ModelAdmin):
|
|
|
|
"""
|
|
A ModelAdmin subclass that provides full-text search integration.
|
|
|
|
Subclass this admin class and specify a tuple of search_fields for instant
|
|
integration!
|
|
"""
|
|
|
|
search_engine = admin_search_engine
|
|
|
|
search_adapter_cls = SearchAdapter
|
|
|
|
@property
|
|
def search_context_manager(self):
|
|
"""The search context manager used by this SearchAdmin."""
|
|
return self.search_engine._search_context_manager
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
"""Initializes the search admin."""
|
|
super(SearchAdmin, self).__init__(*args, **kwargs)
|
|
# Check that the search fields are valid.
|
|
for search_field in self.search_fields or ():
|
|
if search_field[0] in ("^", "@", "="):
|
|
raise ValueError("SearchAdmin does not support search fields prefixed with '^', '=' or '@'")
|
|
# Register with the search engine.
|
|
self.register_model_with_watson()
|
|
# Set up revision contexts on key methods, just in case.
|
|
self.add_view = self.search_context_manager.update_index()(self.add_view)
|
|
self.change_view = self.search_context_manager.update_index()(self.change_view)
|
|
self.delete_view = self.search_context_manager.update_index()(self.delete_view)
|
|
self.changelist_view = self.search_context_manager.update_index()(self.changelist_view)
|
|
|
|
def register_model_with_watson(self):
|
|
"""Registers this admin class' model with django-watson."""
|
|
if not self.search_engine.is_registered(self.model) and self.search_fields:
|
|
self.search_engine.register(
|
|
self.model,
|
|
fields=self.search_fields,
|
|
adapter_cls=self.search_adapter_cls,
|
|
get_live_queryset=lambda self_: None, # Ensure complete queryset is used in admin.
|
|
)
|
|
|
|
def get_changelist(self, request, **kwargs):
|
|
"""Returns the ChangeList class for use on the changelist page."""
|
|
return WatsonSearchChangeList
|