Ticket #2707: patch4.diff
File patch4.diff, 7.0 KB (added by , 18 years ago) |
---|
-
django/contrib/search/base.py
27 27 # FIXME: This whole function is either silly or clever... 28 28 objPath = string.split('.') 29 29 model = None 30 31 30 if namespace is None: 32 31 # FIXME: This uses the sys._getframe hack to get the caller's namespace. 33 32 obj = sys._getframe(1).f_globals … … 70 69 # but sure makes things like this harder. Hopefully setting this attribute 71 70 # won't mess anything up... 72 71 obj._model = model 72 73 73 return obj 74 74 75 75 class PseudoField(str): 76 """Dirty class used to generete a pseudo-field with the "name" attribute""" 77 def __init__(self,name): 78 self.name = name.split('.')[1] 79 def upper(self): 80 return self.name.upper() 81 76 82 class Indexer(object): 77 83 def __init__(self, path, model, fields=None, attributes=None, namespace=None, **kwargs): 78 84 """Initialize an Indexer whose index data is stored at `path`. … … 137 143 138 144 # FIXME: Detect duplicates, or user-knows-best? 139 145 if isinstance(field, basestring): 140 field = str_to_field(field, namespace) 146 try: 147 field = str_to_field(field, namespace) 148 except models.fields.FieldDoesNotExist: 149 # TODO: How call the function here? 150 # Follow the dirty solution 151 field = PseudoField(field) 141 152 142 153 if name: 143 154 self.attr_fields[name] = field -
django/contrib/search/lucene.py
93 93 for name, field in self.attr_fields.iteritems(): 94 94 # FIXME: Assumes no Foreign Keys! Lame! 95 95 value = getattr(row, field.name) 96 # If the field is a function, they should be called 97 if callable(value): 98 field_value = str(value()) 99 else: 100 field_value = str(value) 101 96 102 document.add(PyLucene.Field(name, str(value), 97 103 PyLucene.Field.Store.YES, 98 104 PyLucene.Field.Index.TOKENIZED)) -
django/contrib/search/xapian.py
4 4 import xapwrap.document 5 5 from itertools import imap 6 6 7 from base import Indexer, ResultSet 7 from query import ResultSet, Hit 8 from base import Indexer 8 9 9 10 # TODO: This is incomplete. 10 11 11 12 class XapianIndexer(Indexer): 12 13 def update(self, documents=None): 13 idx = xapwrap.index. Index(self.path, True)14 idx = xapwrap.index.SmartIndex(self.path, True) 14 15 15 16 if documents is None: 16 17 update_queue = self.model.objects.all() 17 18 else: 18 19 update_queue = documents 19 20 20 for row in documents:21 for row in update_queue: 21 22 keys = [] 23 text_fields = [] 24 keywords = [] 22 25 for name, field in self.attr_fields.iteritems(): 23 keys.append(xapwrap.document.SortKey(name, getattr(self.model, field.name))) 26 # Get the field value based in the field name 27 field_value = getattr(row, field.name) 28 if callable(field_value): 29 field_value = str(field_value()) 30 else: 31 field_value = str(field_value) 32 33 # Keys used for sort 34 keys.append(xapwrap.document.SortKey(name, field_value)) 24 35 25 d = xapwrap.document.Document(textFields=fields, sortFields=keys, uid=row._get_pk_val()) 36 # Text used for order_by 37 text_fields.append(xapwrap.document.TextField(name,field_value)) 38 text_fields.append(xapwrap.document.TextField(name,field_value,True)) 39 d = xapwrap.document.Document( 40 textFields=text_fields, 41 sortFields=keys, 42 uid=row._get_pk_val(), 43 ) 26 44 idx.index(d) 45 27 46 idx.close() 28 47 29 48 def search(self, query, order_by='RELEVANCE'): 30 idx = Index(self.path) 49 idx = xapwrap.index.SmartIndex(self.path) 50 prefixMap = {} 51 for name, field in self.attr_fields.iteritems(): 52 prefixMap[name] = name 53 idx.configure(prefixMap=prefixMap) 54 55 31 56 if order_by == 'RELEVANCE': 32 57 results = idx.search(query, sortByRelevence=True) 33 58 else: … … 36 61 ascending = False 37 62 while order_by[0] in '+-': 38 63 order_by = order_by[1:] 64 39 65 results = idx.search(query, order_by, sortAscending=ascending) 40 return XapianResultSet(results )66 return XapianResultSet(results,self) 41 67 42 68 43 69 class XapianResultSet(ResultSet): … … 49 75 return len(self._hits) 50 76 51 77 def __iter__(self): 52 for hit in self._hits ):53 yield XapianHit(hit, 78 for hit in self._hits: 79 yield XapianHit(hit,self._indexer) 54 80 81 def __getitem__(self,pos): 82 '''Allow use index-based access''' 83 return XapianHit(self._hits[pos],self._indexer) 84 85 def __getslice__(self,start,end): 86 '''Allows use slices to retrive the information 87 WARNING: This returns a generator, not a "list" 88 ''' 89 for hit in self._hits[start:end]: 90 yield XapianHit(hit,self._indexer) 55 91 56 class XapianHit( object):92 class XapianHit(Hit): 57 93 def get_pk(self): 58 return self.data['pk'] 94 # FIXME: Hardcoded 'pk' field. 95 return self.data['uid'] 59 96 97 def __getitem__(self, item): 98 return self.data.__getitem__(item) 99 60 100 def get_score(self): 61 101 return self.data['score'] 62 102 -
django/contrib/search/query.py
10 10 def __len__(self): 11 11 raise NotImplementedError 12 12 13 def __getitem__(self ):13 def __getitem__(self,pos): 14 14 raise NotImplementedError 15 15 16 16 … … 29 29 30 30 def get_pk(self): 31 31 raise NotImplementedError 32 33 def get_object(self): 34 return self.model.objects.get(pk=self.get_pk()) 32 35 33 36 def __repr__(self): 34 return "<%s: %s %s, Score:%s>" % (self.__class__.__name__,37 return "<%s: Model:%s pk:%s, Score:%s>" % (self.__class__.__name__, 35 38 self.model._meta, 36 39 self.get_pk(), self.score) 40 No newline at end of file