<s> import mongoengine <EOL> from flask . ext . admin . _compat import string_types , as_unicode , iteritems <EOL> from flask . ext . admin . model . ajax import AjaxModelLoader , DEFAULT_PAGE_SIZE <EOL> class QueryAjaxModelLoader ( AjaxModelLoader ) : <EOL> def __init__ ( self , name , model , ** options ) : <EOL> """<STR_LIT>""" <EOL> super ( QueryAjaxModelLoader , self ) . __init__ ( name , options ) <EOL> self . model = model <EOL> self . fields = options . get ( '<STR_LIT>' ) <EOL> self . _cached_fields = self . _process_fields ( ) <EOL> if not self . fields : <EOL> raise ValueError ( '<STR_LIT>' % ( model , self . name ) ) <EOL> def _process_fields ( self ) : <EOL> remote_fields = [ ] <EOL> for field in self . fields : <EOL> if isinstance ( field , string_types ) : <EOL> attr = getattr ( self . model , field , None ) <EOL> if not attr : <EOL> raise ValueError ( '<STR_LIT>' % ( self . model , field ) ) <EOL> remote_fields . append ( attr ) <EOL> else : <EOL> remote_fields . append ( field ) <EOL> return remote_fields <EOL> def format ( self , model ) : <EOL> if not model : <EOL> return None <EOL> return ( as_unicode ( model . id ) , as_unicode ( model ) ) <EOL> def get_one ( self , pk ) : <EOL> return self . model . objects . filter ( id = pk ) . first ( ) <EOL> def get_list ( self , term , offset = <NUM_LIT:0> , limit = DEFAULT_PAGE_SIZE ) : <EOL> query = self . model . objects <EOL> criteria = None <EOL> for field in self . _cached_fields : <EOL> flt = { u'<STR_LIT>' % field . name : term } <EOL> if not criteria : <EOL> criteria = mongoengine . Q ( ** flt ) <EOL> else : <EOL> criteria |= mongoengine . Q ( ** flt ) <EOL> query = query . filter ( criteria ) <EOL> if offset : <EOL> query = query . skip ( offset ) <EOL> return query . limit ( limit ) . all ( ) <EOL> def create_ajax_loader ( model , name , field_name , opts ) : <EOL> prop = getattr ( model , field_name , None ) <EOL> if prop is None : <EOL> raise ValueError ( '<STR_LIT>' % ( model , field_name ) ) <EOL> ftype = type ( prop ) . __name__ <EOL> if ftype == '<STR_LIT>' : <EOL> prop = prop . field <EOL> ftype = type ( prop ) . __name__ <EOL> if ftype != '<STR_LIT>' : <EOL> raise ValueError ( '<STR_LIT>' % ftype ) <EOL> remote_model = prop . document_type <EOL> return QueryAjaxModelLoader ( name , remote_model , ** opts ) <EOL> def process_ajax_references ( references , view ) : <EOL> def make_name ( base , name ) : <EOL> if base : <EOL> return ( '<STR_LIT>' % ( base , name ) ) . lower ( ) <EOL> else : <EOL> return as_unicode ( name ) . lower ( ) <EOL> def handle_field ( field , subdoc , base ) : <EOL> ftype = type ( field ) . __name__ <EOL> if ftype == '<STR_LIT>' : <EOL> child_doc = getattr ( subdoc , '<STR_LIT>' , { } ) . get ( None ) <EOL> if child_doc : <EOL> handle_field ( field . field , child_doc , base ) <EOL> elif ftype == '<STR_LIT>' : <EOL> result = { } <EOL> ajax_refs = getattr ( subdoc , '<STR_LIT>' , { } ) <EOL> for field_name , opts in iteritems ( ajax_refs ) : <EOL> child_name = make_name ( base , field_name ) <EOL> if isinstance ( opts , dict ) : <EOL> loader = create_ajax_loader ( field . document_type_obj , child_name , field_name , opts ) <EOL> else : <EOL> loader = opts <EOL> result [ field_name ] = loader <EOL> references [ child_name ] = loader <EOL> subdoc . _form_ajax_refs = result <EOL> child_doc = getattr ( subdoc , '<STR_LIT>' , None ) <EOL> if child_doc : <EOL> handle_subdoc ( field . document_type_obj , subdoc , base ) <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' % ( field , ) ) <EOL> def handle_subdoc ( model , subdoc , base ) : <EOL> documents = getattr ( subdoc , '<STR_LIT>' , { } ) <EOL> for name , doc in iteritems ( documents ) : <EOL> field = getattr ( model , name , None ) <EOL> if not field : <EOL> raise ValueError ( '<STR_LIT>' % ( model , name ) ) <EOL> handle_field ( field , doc , make_name ( base , name ) ) <EOL> handle_subdoc ( view . model , view , '<STR_LIT>' ) <EOL> return references </s>
