def get_engine(engine_slug_): """returns search engine with a given name""" try: return [ x[1] for x in SearchEngine.get_created_engines() if x[0] == engine_slug_ ][0] except IndexError: raise CommandError("Search Engine \"%s\" is not registered!" % force_text(engine_slug_))
"""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
def handle(self, *args, **options): """Runs the management command.""" activate(settings.LANGUAGE_CODE) verbosity = int(options.get("verbosity", 1)) # see if we're asked to use a specific search engine if options.get('engine'): engine_slug = options['engine'] engine_selected = True else: engine_slug = "default" engine_selected = False # work-around for legacy optparser hack in BaseCommand. In Django=1.10 the # args are collected in options['apps'], but in earlier versions they are # kept in args. if len(options['apps']): args = options['apps'] # get the search engine we'll be checking registered models for, may be "default" search_engine = get_engine(engine_slug) models = [] for model_name in args: try: model = apps.get_model(*model_name.split(".")) # app label, model name except TypeError: # were we given only model name without app_name? registered_models = search_engine.get_registered_models() matching_models = [x for x in registered_models if x.__name__ == model_name] if len(matching_models) > 1: raise CommandError("Model name \"%s\" is not unique, cannot continue!" % model_name) if matching_models: model = matching_models[0] else: model = None if model is None or not search_engine.is_registered(model): raise CommandError("Model \"%s\" is not registered with django-watson search engine \"%s\"!" % (force_text(model_name), force_text(engine_slug))) models.append(model) refreshed_model_count = 0 if models: # request for (re-)building index for a subset of registered models if verbosity >= 3: print("Using search engine \"%s\"" % engine_slug) for model in models: refreshed_model_count += rebuild_index_for_model(model, engine_slug, verbosity) else: # full rebuild (for one or all search engines) if engine_selected: engine_slugs = [engine_slug] if verbosity >= 2: # let user know the search engine if they selected one print("Rebuilding models registered with search engine \"%s\"" % force_text(engine_slug)) else: # loop through all engines engine_slugs = [x[0] for x in SearchEngine.get_created_engines()] for engine_slug in engine_slugs: search_engine = get_engine(engine_slug) registered_models = search_engine.get_registered_models() # Rebuild the index for all registered models. for model in registered_models: refreshed_model_count += rebuild_index_for_model(model, engine_slug, verbosity) # Clean out any search entries that exist for stale content types. Only do it during full rebuild valid_content_types = [ContentType.objects.get_for_model(model) for model in registered_models] stale_entries = SearchEntry.objects.filter( engine_slug = engine_slug, ).exclude( content_type__in = valid_content_types ) stale_entry_count = stale_entries.count() if stale_entry_count > 0: stale_entries.delete() if verbosity >= 1: print("Deleted {stale_entry_count} stale search entry(s) in {engine_slug!r} search engine.".format( stale_entry_count = stale_entry_count, engine_slug = force_text(engine_slug), )) if verbosity == 1: print("Refreshed {refreshed_model_count} search entry(s) in {engine_slug!r} search engine.".format( refreshed_model_count = refreshed_model_count, engine_slug = force_text(engine_slug), ))
def get_engine(engine_slug_): '''returns search engine with a given name''' try: return [x[1] for x in SearchEngine.get_created_engines() if x[0] == engine_slug_][0] except IndexError: raise CommandError("Search Engine \"%s\" is not registered!" % force_text(engine_slug_))
def handle(self, *args, **options): """Runs the management command.""" activate(settings.LANGUAGE_CODE) verbosity = int(options.get("verbosity", 1)) # see if we're asked to use a specific search engine if options.get('engine'): engine_slug = options['engine'] engine_selected = True else: engine_slug = "default" engine_selected = False # work-around for legacy optparser hack in BaseCommand. In Django=1.10 the # args are collected in options['apps'], but in earlier versions they are # kept in args. if len(options['apps']): args = options['apps'] # get the search engine we'll be checking registered models for, may be "default" search_engine = get_engine(engine_slug) models = [] for model_name in args: try: model = apps.get_model( *model_name.split(".")) # app label, model name except TypeError: # were we given only model name without app_name? registered_models = search_engine.get_registered_models() matching_models = [ x for x in registered_models if x.__name__ == model_name ] if len(matching_models) > 1: raise CommandError( "Model name \"%s\" is not unique, cannot continue!" % model_name) if matching_models: model = matching_models[0] else: model = None if model is None or not search_engine.is_registered(model): raise CommandError( "Model \"%s\" is not registered with django-watson search engine \"%s\"!" % (force_text(model_name), force_text(engine_slug))) models.append(model) refreshed_model_count = 0 if models: # request for (re-)building index for a subset of registered models if verbosity >= 3: print("Using search engine \"%s\"" % engine_slug) for model in models: refreshed_model_count += rebuild_index_for_model( model, engine_slug, verbosity) else: # full rebuild (for one or all search engines) if engine_selected: engine_slugs = [engine_slug] if verbosity >= 2: # let user know the search engine if they selected one print( "Rebuilding models registered with search engine \"%s\"" % force_text(engine_slug)) else: # loop through all engines engine_slugs = [ x[0] for x in SearchEngine.get_created_engines() ] for engine_slug in engine_slugs: search_engine = get_engine(engine_slug) registered_models = search_engine.get_registered_models() # Rebuild the index for all registered models. for model in registered_models: refreshed_model_count += rebuild_index_for_model( model, engine_slug, verbosity) # Clean out any search entries that exist for stale content types. # Only do it during full rebuild valid_content_types = [ ContentType.objects.get_for_model(model) for model in registered_models ] stale_entries = SearchEntry.objects.filter( engine_slug=engine_slug, ).exclude( content_type__in=valid_content_types) stale_entry_count = stale_entries.count() if stale_entry_count > 0: stale_entries.delete() if verbosity >= 1: print("Deleted {stale_entry_count} stale search entry(s) " "in {engine_slug!r} search engine.".format( stale_entry_count=stale_entry_count, engine_slug=force_text(engine_slug), )) if verbosity == 1: print("Refreshed {refreshed_model_count} search entry(s) " "in {engine_slug!r} search engine.".format( refreshed_model_count=refreshed_model_count, engine_slug=force_text(engine_slug), ))