Django

Code

Ticket #2707: patch3.diff

File patch3.diff, 6.4 kB (added by sdm@garimpar.com, 2 years ago)

Final (?) version

  • django/contrib/search/base.py

    old new  
    2727    # FIXME: This whole function is either silly or clever... 
    2828    objPath = string.split('.') 
    2929    model = None 
    30  
    3130    if namespace is None: 
    3231        # FIXME: This uses the sys._getframe hack to get the caller's namespace. 
    3332        obj = sys._getframe(1).f_globals 
     
    7069    # but sure makes things like this harder. Hopefully setting this attribute 
    7170    # won't mess anything up... 
    7271    obj._model = model 
     72         
    7373    return obj 
    7474 
    75  
     75class 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     
    7682class Indexer(object): 
    7783    def __init__(self, path, model, fields=None, attributes=None, namespace=None, **kwargs): 
    7884        """Initialize an Indexer whose index data is stored at `path`. 
     
    137143 
    138144        # FIXME: Detect duplicates, or user-knows-best? 
    139145        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) 
    141152 
    142153        if name: 
    143154            self.attr_fields[name] = field 
  • django/contrib/search/lucene.py

    old new  
    9393        for name, field in self.attr_fields.iteritems(): 
    9494            # FIXME: Assumes no Foreign Keys! Lame! 
    9595            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             
    96102            document.add(PyLucene.Field(name, str(value), 
    97103                                        PyLucene.Field.Store.YES, 
    98104                                        PyLucene.Field.Index.TOKENIZED)) 
  • django/contrib/search/xapian.py

    old new  
    44import xapwrap.document 
    55from itertools import imap 
    66 
    7 from base import Indexer, ResultSet 
     7from query import ResultSet, Hit 
     8from base import Indexer 
    89 
    910# TODO: This is incomplete. 
    1011 
    1112class XapianIndexer(Indexer): 
    1213    def update(self, documents=None): 
    13         idx = xapwrap.index.Index(self.path, True) 
     14        idx = xapwrap.index.SmartIndex(self.path, True) 
    1415 
    1516        if documents is None: 
    1617            update_queue = self.model.objects.all() 
    1718        else: 
    1819            update_queue = documents 
    1920 
    20         for row in documents
     21        for row in update_queue
    2122            keys = [] 
     23            text_fields = [] 
     24            keywords = [] 
    2225            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)) 
    2435 
    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                                         ) 
    2644            idx.index(d) 
     45             
    2746        idx.close() 
    2847 
    2948    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         
    3156        if order_by == 'RELEVANCE': 
    3257            results = idx.search(query, sortByRelevence=True) 
    3358        else: 
     
    3661                ascending = False 
    3762            while order_by[0] in '+-': 
    3863                order_by = order_by[1:] 
     64             
    3965            results = idx.search(query, order_by, sortAscending=ascending) 
    40         return XapianResultSet(results
     66        return XapianResultSet(results,self
    4167 
    4268 
    4369class XapianResultSet(ResultSet): 
     
    4975        return len(self._hits) 
    5076 
    5177    def __iter__(self): 
    52         for hit in self._hits)
    53             yield XapianHit(hit, self._indexer) 
     78        for hit in self._hits
     79            yield XapianHit(hit,self._indexer) 
    5480 
    5581 
    56 class XapianHit(object): 
     82class XapianHit(Hit): 
    5783    def get_pk(self): 
    58         return self.data['pk'] 
     84        # FIXME: Hardcoded 'pk' field. 
     85        return self.data['uid'] 
    5986 
     87    def __getitem__(self, item): 
     88        return self.data.__getitem__(item) 
     89 
    6090    def get_score(self): 
    6191        return self.data['score'] 
    6292 
  • django/contrib/search/query.py

    old new  
    2929 
    3030    def get_pk(self): 
    3131        raise NotImplementedError 
     32     
     33    def get_object(self): 
     34        return self.model.objects.get(pk=self.get_pk()) 
    3235 
    3336    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__, 
    3538                                           self.model._meta, 
    3639                                           self.get_pk(), self.score)