#NEWLINE# def search( self , query , search_fields = None ) : #NEWLINE# #INDENT# '\n        Build a queryset matching words in the given search query,\n        treating quoted terms as exact phrases and taking into\n        account + and - symbols as modifiers controlling which terms\n        to require and exclude.\n        ' #NEWLINE# if search_fields : #NEWLINE# #INDENT# self . _search_fields = search_fields_to_dict ( search_fields ) #NEWLINE# #UNINDENT# if ( not self . _search_fields ) : #NEWLINE# #INDENT# return self . none ( ) #NEWLINE# #UNINDENT# terms = ' ' . join ( query . split ( ) ) . replace ( '+ ' , '+' ) . replace ( '+"' , '"+' ) . replace ( '- ' , '-' ) . replace ( '-"' , '"-' ) . split ( '"' ) #NEWLINE# terms = [ ( ( '' if ( t [ 0 : 1 ] not in '+-' ) else t [ 0 : 1 ] ) + t . strip ( punctuation ) ) for t in ( optional [ 1 : : 2 ] + '' . join ( terms [ : : 2 ] ) . split ( ) ) ] #NEWLINE# terms_no_stopwords = [ t for t in terms if ( t . lower ( ) not in settings . STOP_WORDS ) ] #NEWLINE# get_positive_terms = ( lambda terms : [ t . lower ( ) . strip ( punctuation ) for t in terms if ( t [ 0 : 1 ] != '-' ) ] ) #NEWLINE# positive_terms = get_positive_terms ( terms_no_stopwords ) #NEWLINE# if positive_terms : #NEWLINE# #INDENT# terms = terms_no_stopwords #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# positive_terms = get_positive_terms ( terms ) #NEWLINE# #UNINDENT# if ( not positive_terms ) : #NEWLINE# #INDENT# return self . none ( ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# self . _search_terms . update ( positive_terms ) #NEWLINE# #UNINDENT# excluded = [ reduce ( iand , [ ( ~ Q ( ** { #NEWLINE# #INDENT# ( '%s__icontains' % f ) : t [ 1 : ] , #NEWLINE# #UNINDENT# } ) ) for f in self . _search_fields . keys ( ) ] ) for t in terms if ( t [ 0 : 1 ] == '-' ) ] #NEWLINE# required = [ reduce ( ior , [ Q ( ** { #NEWLINE# #INDENT# ( '%s__icontains' % f ) : t [ 1 : ] , #NEWLINE# #UNINDENT# } ) for f in self . _search_fields . keys ( ) ] ) for t in terms if ( t [ 0 : 1 ] == '+' ) ] #NEWLINE# optional = [ reduce ( ior , [ Q ( ** { #NEWLINE# #INDENT# ( '%s__icontains' % f ) : t , #NEWLINE# #UNINDENT# } ) for f in self . _search_fields . keys ( ) ] ) for t in terms if ( t [ 0 : 1 ] not in '+-' ) ] #NEWLINE# queryset = self #NEWLINE# if excluded : #NEWLINE# #INDENT# queryset = queryset . filter ( reduce ( iand , excluded ) ) #NEWLINE# #UNINDENT# if required : #NEWLINE# #INDENT# queryset = queryset . filter ( reduce ( iand , required ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if optional : #NEWLINE# #INDENT# queryset = queryset . filter ( reduce ( ior , optional ) ) #NEWLINE# #UNINDENT# #UNINDENT# return queryset . distinct ( )