Ticket #2707: patch2.diff

File patch2.diff, 6.1 KB (added by sdm@…, 9 years ago)
  • django/contrib/search/base.py

     
    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

     
    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

     
    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            prefixes = {}
    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            d = xapwrap.document.Document(textFields=text_fields,sortFields=keys, uid=row._get_pk_val())
     39            idx.configure(prefixMap=prefixes)
    2640            idx.index(d)
     41           
    2742        idx.close()
    2843
    2944    def search(self, query, order_by='RELEVANCE'):
    30         idx = Index(self.path)
     45        idx = xapwrap.index.SmartIndex(self.path)
    3146        if order_by == 'RELEVANCE':
    3247            results = idx.search(query, sortByRelevence=True)
    3348        else:
     
    3651                ascending = False
    3752            while order_by[0] in '+-':
    3853                order_by = order_by[1:]
     54               
    3955            results = idx.search(query, order_by, sortAscending=ascending)
    40         return XapianResultSet(results)
     56        return XapianResultSet(results,self)
    4157
    4258
    4359class XapianResultSet(ResultSet):
     
    4965        return len(self._hits)
    5066
    5167    def __iter__(self):
    52         for hit in self._hits):
    53             yield XapianHit(hit, self._indexer)
     68        for hit in self._hits:
     69            yield XapianHit(hit,self._indexer)
    5470
    5571
    56 class XapianHit(object):
     72class XapianHit(Hit):
    5773    def get_pk(self):
    58         return self.data['pk']
     74        # FIXME: Hardcoded 'pk' field.
     75        return self.data['uid']
    5976
     77    def __getitem__(self, item):
     78        return self.data.__getitem__(item)
     79
    6080    def get_score(self):
    6181        return self.data['score']
    6282
    6383    score = property(get_score)
    64 
  • django/contrib/search/query.py

     
    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)
     40 No newline at end of file
Back to Top