Anonymous avatar Anonymous committed 50f60eb

fixed problem with relation index and default manager, fixed RelationIndexQueries using array like element selection, fixed tests

Comments (0)

Files changed (3)

search/__init__.py

-from search.core import default_splitter, site_language, SearchManager, \
-    install_index_model
-
-def autodiscover():
-    """
-    Automatically add managers from search_indexes modules.
-    """
-    import imp
-    from django.conf import settings
-    from django.utils.importlib import import_module
-
-    for app in settings.INSTALLED_APPS:
-        # For each app, we need to look for an search_indexes.py inside that app's
-        # package. We can't use os.path here -- recall that modules may be
-        # imported different ways (think zip files) -- so we need to get
-        # the app's __path__ and look for search_indexes.py on that path.
-
-        # Step 1: find out the app's __path__ Import errors here will (and
-        # should) bubble up, but a missing __path__ (which is legal, but weird)
-        # fails silently -- apps that do weird things with __path__ might
-        # need to roll their own index registration.
-        try:
-            app_path = import_module(app).__path__
-        except AttributeError:
-            continue
-
-        # Step 2: use imp.find_module to find the app's search_indexes.py. For some
-        # reason imp.find_module raises ImportError if the app can't be found
-        # but doesn't actually try to import the module. So skip this app if
-        # its search_indexes.py doesn't exist
-        try:
-            imp.find_module('search_indexes', app_path)
-        except ImportError:
-            continue
-
-        # Step 3: import the app's search_index file. If this has errors we want them
-        # to bubble up.
-        import_module("%s.search_indexes" % app)
-
-def register(model, fields_to_index, search_index='search_index',
-    indexer=None, splitter=default_splitter, relation_index=True, integrate='*',
-    filters={}, language=site_language, **kwargs):
-
-    """
-    Add a search manager to the model.
-    """
-
-    if not hasattr(model, '_meta'):
-        raise AttributeError('The model being registered must derive from Model.')
-
-    if hasattr(model, search_index):
-        raise AttributeError('The model being registered already defines a'
-            ' property called %s.' % search_index)
-
-    model.add_to_class(search_index, SearchManager(fields_to_index, indexer,
-        splitter, relation_index, integrate, filters, language, **kwargs))
-
+from search.core import default_splitter, site_language, SearchManager, \
+    install_index_model
+
+def autodiscover():
+    """
+    Automatically add managers from search_indexes modules.
+    """
+    import imp
+    from django.conf import settings
+    from django.utils.importlib import import_module
+
+    for app in settings.INSTALLED_APPS:
+        # For each app, we need to look for an search_indexes.py inside that app's
+        # package. We can't use os.path here -- recall that modules may be
+        # imported different ways (think zip files) -- so we need to get
+        # the app's __path__ and look for search_indexes.py on that path.
+
+        # Step 1: find out the app's __path__ Import errors here will (and
+        # should) bubble up, but a missing __path__ (which is legal, but weird)
+        # fails silently -- apps that do weird things with __path__ might
+        # need to roll their own index registration.
+        try:
+            app_path = import_module(app).__path__
+        except AttributeError:
+            continue
+
+        # Step 2: use imp.find_module to find the app's search_indexes.py. For some
+        # reason imp.find_module raises ImportError if the app can't be found
+        # but doesn't actually try to import the module. So skip this app if
+        # its search_indexes.py doesn't exist
+        try:
+            imp.find_module('search_indexes', app_path)
+        except ImportError:
+            continue
+
+        # Step 3: import the app's search_index file. If this has errors we want them
+        # to bubble up.
+        import_module("%s.search_indexes" % app)
+
+def register(model, fields_to_index, search_index='search_index',
+    indexer=None, splitter=default_splitter, relation_index=True, integrate='*',
+    filters={}, language=site_language, **kwargs):
+
+    """
+    Add a search manager to the model.
+    """
+
+    if not hasattr(model, '_meta'):
+        raise AttributeError('The model being registered must derive from Model.')
+
+    if hasattr(model, search_index):
+        raise AttributeError('The model being registered already defines a'
+            ' property called %s.' % search_index)
+
+    model.add_to_class(search_index, SearchManager(fields_to_index, indexer,
+        splitter, relation_index, integrate, filters, language, **kwargs))
+
     install_index_model(model)
         # set default_manager to None such that the default_manager will be set
         # to 'objects' via the class-prepared signal calling
         # ensure_default_manager
-        setattr(model, '_default_manager', None)
+#        setattr(model, '_default_manager', None)
         self.name = name
         # add IndexField to the model if we do not use the relation_index
         if not self.relation_index:
         attrs = dict(__module__=self.__module__)
         # By default we integrate everything when using relation index
         # manager will add the IndexField to the relation index automaticaly
-        if self.relation_index and self.integrate == ('*',):
+        if self.integrate == ('*',):
             self.integrate = tuple(field.name
                                    for field in self.model._meta.fields
                                    if not isinstance(field, IndexField))
                     self.model._meta.object_name.lower(),
                     self.name, field_name,
                 )
-        manager_name = self.name
-        attrs[manager_name] = SearchManager(self.fields_to_index,
-            splitter=self.splitter, indexer=self.indexer,
-            language=self.language, relation_index=False)
-        if self.relation_index:
-            owner = self
-            def __init__(self, *args, **kwargs):
-                # Save some space: don't copy the whole indexed text into the
-                # relation index field unless the field gets integrated.
-                field_names = [field.name for field in self._meta.fields]
-                owner_field_names = [field.name
-                                     for field in owner.model._meta.fields]
-                for key, value in kwargs.items():
-                    if key in field_names or key not in owner_field_names:
-                        continue
-                    setattr(self, key, value)
-                    del kwargs[key]
-                models.Model.__init__(self, *args, **kwargs)
-            attrs['__init__'] = __init__
-            self._relation_index_model = type(
-                'RelationIndex_%s_%s_%s' % (self.model._meta.app_label,
-                                            self.model._meta.object_name,
-                                            self.name),
-                (models.Model,), attrs)
+
+        owner = self
+        def __init__(self, *args, **kwargs):
+            # Save some space: don't copy the whole indexed text into the
+            # relation index field unless the field gets integrated.
+            field_names = [field.name for field in self._meta.fields]
+            owner_field_names = [field.name
+                                 for field in owner.model._meta.fields]
+            for key, value in kwargs.items():
+                if key in field_names or key not in owner_field_names:
+                    continue
+                setattr(self, key, value)
+                del kwargs[key]
+            models.Model.__init__(self, *args, **kwargs)
+        attrs['__init__'] = __init__
+
+        self._relation_index_model = type(
+            'RelationIndex_%s_%s_%s' % (self.model._meta.app_label,
+                                        self.model._meta.object_name,
+                                        self.name),
+            (models.Model,), attrs)
+        self._relation_index_model.add_to_class(self.name, SearchManager(
+            self.fields_to_index, splitter=self.splitter, indexer=self.indexer,
+            language=self.language, relation_index=False))
 
     def get_index_values(self, parent):
         filters = []
         return self
 
     def __getitem__(self, index):
+        pks_slice = index
+        if not isinstance(index, slice):
+            pks_slice = slice(None, index + 1, None)
+
         pks = [instance.pk if isinstance(instance, models.Model) else instance['pk']
-                for instance in self.query[index]]
-        return [item for item in self.model.objects.filter(
-            pk__in=pks) if item]
+                for instance in self.query[pks_slice]]
+        if not isinstance(index, slice):
+            return self.model.objects.filter(pk__in=pks)[index]
+        return self.model.objects.filter(pk__in=pks)[pks_slice]
+#        return [item for item in self.model.objects.filter(
+#            pk__in=pks) if item]
+        
 
     def count(self):
         return self.query.count()
     check = models.BooleanField()
     value = models.CharField(max_length=500)
 
-register(Indexed, 'one_index', 'one', indexer=startswith)
-register(Indexed, 'one_two_index', ('one', 'two'))
-register(Indexed, 'value_index', 'value', integrate=('one', 'check'))
+register(Indexed, 'one', search_index='one_index', indexer=startswith)
+register(Indexed, ('one', 'two'), search_index='one_two_index')
+register(Indexed, 'value', integrate=('one', 'check'), search_index='value_index')
 
 # Test filters
 class FiltersIndexed(models.Model):
     value = models.CharField(max_length=500)
     check = models.BooleanField()
 
-register(FiltersIndexed, 'checked_index', 'value', filters={'check':True, })
+register(FiltersIndexed, 'value', filters={'check':True, }, search_index='checked_index')
 
 class TestIndexed(TestCase):
     def setUp(self):
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.