<s> from wtforms import fields , validators <EOL> from sqlalchemy import Boolean , Column <EOL> from flask . ext . admin import form <EOL> from flask . ext . admin . model . form import ( converts , ModelConverterBase , <EOL> InlineModelConverterBase , FieldPlaceholder ) <EOL> from flask . ext . admin . model . fields import AjaxSelectField , AjaxSelectMultipleField <EOL> from flask . ext . admin . model . helpers import prettify_name <EOL> from flask . ext . admin . _backwards import get_property <EOL> from flask . ext . admin . _compat import iteritems <EOL> from . validators import Unique <EOL> from . fields import QuerySelectField , QuerySelectMultipleField , InlineModelFormList <EOL> from . tools import has_multiple_pks , filter_foreign_columns <EOL> from . ajax import create_ajax_loader <EOL> try : <EOL> from wtforms . ext . dateutil . fields import DateTimeField <EOL> except ImportError : <EOL> from wtforms . fields import DateTimeField <EOL> class AdminModelConverter ( ModelConverterBase ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , session , view ) : <EOL> super ( AdminModelConverter , self ) . __init__ ( ) <EOL> self . session = session <EOL> self . view = view <EOL> def _get_label ( self , name , field_args ) : <EOL> """<STR_LIT>""" <EOL> if '<STR_LIT:label>' in field_args : <EOL> return field_args [ '<STR_LIT:label>' ] <EOL> column_labels = get_property ( self . view , '<STR_LIT>' , '<STR_LIT>' ) <EOL> if column_labels : <EOL> return column_labels . get ( name ) <EOL> prettify_override = getattr ( self . view , '<STR_LIT>' , None ) <EOL> if prettify_override : <EOL> return prettify_override ( name ) <EOL> return prettify_name ( name ) <EOL> def _get_description ( self , name , field_args ) : <EOL> if '<STR_LIT:description>' in field_args : <EOL> return field_args [ '<STR_LIT:description>' ] <EOL> column_descriptions = getattr ( self . view , '<STR_LIT>' , None ) <EOL> if column_descriptions : <EOL> return column_descriptions . get ( name ) <EOL> def _get_field_override ( self , name ) : <EOL> form_overrides = getattr ( self . view , '<STR_LIT>' , None ) <EOL> if form_overrides : <EOL> return form_overrides . get ( name ) <EOL> return None <EOL> def _model_select_field ( self , prop , multiple , remote_model , ** kwargs ) : <EOL> loader = getattr ( self . view , '<STR_LIT>' , { } ) . get ( prop . key ) <EOL> if loader : <EOL> if multiple : <EOL> return AjaxSelectMultipleField ( loader , ** kwargs ) <EOL> else : <EOL> return AjaxSelectField ( loader , ** kwargs ) <EOL> if '<STR_LIT>' not in kwargs : <EOL> kwargs [ '<STR_LIT>' ] = lambda : self . session . query ( remote_model ) <EOL> if '<STR_LIT>' not in kwargs : <EOL> if multiple : <EOL> kwargs [ '<STR_LIT>' ] = form . Select2Widget ( multiple = True ) <EOL> else : <EOL> kwargs [ '<STR_LIT>' ] = form . Select2Widget ( ) <EOL> if multiple : <EOL> return QuerySelectMultipleField ( ** kwargs ) <EOL> else : <EOL> return QuerySelectField ( ** kwargs ) <EOL> def _convert_relation ( self , prop , kwargs ) : <EOL> form_columns = getattr ( self . view , '<STR_LIT>' , None ) <EOL> if form_columns and prop . key not in form_columns : <EOL> return None <EOL> remote_model = prop . mapper . class_ <EOL> column = prop . local_remote_pairs [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] <EOL> if not column . foreign_keys : <EOL> column = prop . local_remote_pairs [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] <EOL> kwargs [ '<STR_LIT:label>' ] = self . _get_label ( prop . key , kwargs ) <EOL> kwargs [ '<STR_LIT:description>' ] = self . _get_description ( prop . key , kwargs ) <EOL> requirement_options = ( validators . Optional , validators . InputRequired ) <EOL> if not any ( isinstance ( v , requirement_options ) for v in kwargs [ '<STR_LIT>' ] ) : <EOL> if column . nullable or prop . direction . name != '<STR_LIT>' : <EOL> kwargs [ '<STR_LIT>' ] . append ( validators . Optional ( ) ) <EOL> else : <EOL> kwargs [ '<STR_LIT>' ] . append ( validators . InputRequired ( ) ) <EOL> if '<STR_LIT>' not in kwargs : <EOL> kwargs [ '<STR_LIT>' ] = column . nullable <EOL> override = self . _get_field_override ( prop . key ) <EOL> if override : <EOL> return override ( ** kwargs ) <EOL> if prop . direction . name == '<STR_LIT>' or not prop . uselist : <EOL> return self . _model_select_field ( prop , False , remote_model , ** kwargs ) <EOL> elif prop . direction . name == '<STR_LIT>' : <EOL> return self . _model_select_field ( prop , True , remote_model , ** kwargs ) <EOL> elif prop . direction . name == '<STR_LIT>' : <EOL> return self . _model_select_field ( prop , True , remote_model , ** kwargs ) <EOL> def convert ( self , model , mapper , prop , field_args , hidden_pk ) : <EOL> if isinstance ( prop , FieldPlaceholder ) : <EOL> return form . recreate_field ( prop . field ) <EOL> kwargs = { <EOL> '<STR_LIT>' : [ ] , <EOL> '<STR_LIT>' : [ ] <EOL> } <EOL> if field_args : <EOL> kwargs . update ( field_args ) <EOL> if hasattr ( prop , '<STR_LIT>' ) : <EOL> return self . _convert_relation ( prop , kwargs ) <EOL> else : <EOL> if hasattr ( prop , '<STR_LIT>' ) : <EOL> if len ( prop . columns ) > <NUM_LIT:1> : <EOL> columns = filter_foreign_columns ( model . __table__ , prop . columns ) <EOL> if len ( columns ) > <NUM_LIT:1> : <EOL> raise TypeError ( '<STR_LIT>' % ( model , prop . key ) ) <EOL> column = columns [ <NUM_LIT:0> ] <EOL> else : <EOL> column = prop . columns [ <NUM_LIT:0> ] <EOL> form_columns = getattr ( self . view , '<STR_LIT>' , None ) or ( ) <EOL> if column . foreign_keys and prop . key not in form_columns : <EOL> return None <EOL> if not isinstance ( column , Column ) : <EOL> return None <EOL> unique = False <EOL> if column . primary_key : <EOL> if hidden_pk : <EOL> return fields . HiddenField ( ) <EOL> else : <EOL> if prop . key not in form_columns : <EOL> return None <EOL> if not has_multiple_pks ( model ) : <EOL> kwargs [ '<STR_LIT>' ] . append ( Unique ( self . session , <EOL> model , <EOL> column ) ) <EOL> unique = True <EOL> if column . unique and not unique : <EOL> kwargs [ '<STR_LIT>' ] . append ( Unique ( self . session , <EOL> model , <EOL> column ) ) <EOL> optional_types = getattr ( self . view , '<STR_LIT>' , ( Boolean , ) ) <EOL> if not column . nullable and not isinstance ( column . type , optional_types ) : <EOL> kwargs [ '<STR_LIT>' ] . append ( validators . InputRequired ( ) ) <EOL> if self . view . model == mapper . class_ : <EOL> kwargs [ '<STR_LIT:label>' ] = self . _get_label ( prop . key , kwargs ) <EOL> kwargs [ '<STR_LIT:description>' ] = self . _get_description ( prop . key , kwargs ) <EOL> default = getattr ( column , '<STR_LIT:default>' , None ) <EOL> value = None <EOL> if default is not None : <EOL> value = getattr ( default , '<STR_LIT>' , None ) <EOL> if value is not None : <EOL> if getattr ( default , '<STR_LIT>' , False ) : <EOL> value = lambda : default . arg ( None ) <EOL> else : <EOL> if not getattr ( default , '<STR_LIT>' , True ) : <EOL> value = None <EOL> if value is not None : <EOL> kwargs [ '<STR_LIT:default>' ] = value <EOL> if column . nullable : <EOL> kwargs [ '<STR_LIT>' ] . append ( validators . Optional ( ) ) <EOL> override = self . _get_field_override ( prop . key ) <EOL> if override : <EOL> return override ( ** kwargs ) <EOL> form_choices = getattr ( self . view , '<STR_LIT>' , None ) <EOL> if mapper . class_ == self . view . model and form_choices : <EOL> choices = form_choices . get ( column . key ) <EOL> if choices : <EOL> return form . Select2Field ( <EOL> choices = choices , <EOL> allow_blank = column . nullable , <EOL> ** kwargs <EOL> ) <EOL> converter = self . get_converter ( column ) <EOL> if converter is None : <EOL> return None <EOL> return converter ( model = model , mapper = mapper , prop = prop , <EOL> column = column , field_args = kwargs ) <EOL> return None <EOL> @ classmethod <EOL> def _string_common ( cls , column , field_args , ** extra ) : <EOL> if column . type . length : <EOL> field_args [ '<STR_LIT>' ] . append ( validators . Length ( max = column . type . length ) ) <EOL> @ converts ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> def conv_String ( self , column , field_args , ** extra ) : <EOL> if hasattr ( column . type , '<STR_LIT>' ) : <EOL> field_args [ '<STR_LIT>' ] . append ( validators . AnyOf ( column . type . enums ) ) <EOL> field_args [ '<STR_LIT>' ] = [ ( f , f ) for f in column . type . enums ] <EOL> return form . Select2Field ( ** field_args ) <EOL> if column . nullable : <EOL> filters = field_args . get ( '<STR_LIT>' , [ ] ) <EOL> filters . append ( lambda x : x or None ) <EOL> field_args [ '<STR_LIT>' ] = filters <EOL> self . _string_common ( column = column , field_args = field_args , ** extra ) <EOL> return fields . StringField ( ** field_args ) <EOL> @ converts ( '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' ) <EOL> def conv_Text ( self , field_args , ** extra ) : <EOL> self . _string_common ( field_args = field_args , ** extra ) <EOL> return fields . TextAreaField ( ** field_args ) <EOL> @ converts ( '<STR_LIT>' ) <EOL> def conv_Boolean ( self , field_args , ** extra ) : <EOL> return fields . BooleanField ( ** field_args ) <EOL> @ converts ( '<STR_LIT>' ) <EOL> def convert_date ( self , field_args , ** extra ) : <EOL> field_args [ '<STR_LIT>' ] = form . DatePickerWidget ( ) <EOL> return fields . DateField ( ** field_args ) <EOL> @ converts ( '<STR_LIT>' ) <EOL> def convert_datetime ( self , field_args , ** extra ) : <EOL> return form . DateTimeField ( ** field_args ) <EOL> @ converts ( '<STR_LIT>' ) <EOL> def convert_time ( self , field_args , ** extra ) : <EOL> return form . TimeField ( ** field_args ) <EOL> @ converts ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> def handle_integer_types ( self , column , field_args , ** extra ) : <EOL> unsigned = getattr ( column . type , '<STR_LIT>' , False ) <EOL> if unsigned : <EOL> field_args [ '<STR_LIT>' ] . append ( validators . NumberRange ( min = <NUM_LIT:0> ) ) <EOL> return fields . IntegerField ( ** field_args ) <EOL> @ converts ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> def handle_decimal_types ( self , column , field_args , ** extra ) : <EOL> places = getattr ( column . type , '<STR_LIT>' , <NUM_LIT:2> ) <EOL> if places is not None : <EOL> field_args [ '<STR_LIT>' ] = places <EOL> return fields . DecimalField ( ** field_args ) <EOL> @ converts ( '<STR_LIT>' ) <EOL> def conv_MSYear ( self , field_args , ** extra ) : <EOL> field_args [ '<STR_LIT>' ] . append ( validators . NumberRange ( min = <NUM_LIT> , max = <NUM_LIT> ) ) <EOL> return fields . StringField ( ** field_args ) <EOL> @ converts ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> def conv_PGInet ( self , field_args , ** extra ) : <EOL> field_args . setdefault ( '<STR_LIT:label>' , u'<STR_LIT>' ) <EOL> field_args [ '<STR_LIT>' ] . append ( validators . IPAddress ( ) ) <EOL> return fields . StringField ( ** field_args ) <EOL> @ converts ( '<STR_LIT>' ) <EOL> def conv_PGMacaddr ( self , field_args , ** extra ) : <EOL> field_args . setdefault ( '<STR_LIT:label>' , u'<STR_LIT>' ) <EOL> field_args [ '<STR_LIT>' ] . append ( validators . MacAddress ( ) ) <EOL> return fields . StringField ( ** field_args ) <EOL> @ converts ( '<STR_LIT>' ) <EOL> def conv_PGUuid ( self , field_args , ** extra ) : <EOL> field_args . setdefault ( '<STR_LIT:label>' , u'<STR_LIT>' ) <EOL> field_args [ '<STR_LIT>' ] . append ( validators . UUID ( ) ) <EOL> return fields . StringField ( ** field_args ) <EOL> @ converts ( '<STR_LIT>' ) <EOL> def conv_ARRAY ( self , field_args , ** extra ) : <EOL> return form . Select2TagsField ( save_as_list = True , ** field_args ) <EOL> def _resolve_prop ( prop ) : <EOL> """<STR_LIT>""" <EOL> if hasattr ( prop , '<STR_LIT>' ) : <EOL> return prop . _proxied_property <EOL> return prop <EOL> def get_form ( model , converter , <EOL> base_class = form . BaseForm , <EOL> only = None , <EOL> exclude = None , <EOL> field_args = None , <EOL> hidden_pk = False , <EOL> ignore_hidden = True , <EOL> extra_fields = None ) : <EOL> """<STR_LIT>""" <EOL> if not hasattr ( model , '<STR_LIT>' ) : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> mapper = model . _sa_class_manager . mapper <EOL> field_args = field_args or { } <EOL> properties = ( ( p . key , p ) for p in mapper . iterate_properties ) <EOL> if only : <EOL> props = dict ( properties ) <EOL> def find ( name ) : <EOL> if extra_fields and name in extra_fields : <EOL> return FieldPlaceholder ( extra_fields [ name ] ) <EOL> p = props . get ( name ) <EOL> if p is not None : <EOL> return p <EOL> p = getattr ( model , name , None ) <EOL> if p is not None and hasattr ( p , '<STR_LIT>' ) : <EOL> return p . property <EOL> raise ValueError ( '<STR_LIT>' % ( model , name ) ) <EOL> properties = ( ( x , find ( x ) ) for x in only ) <EOL> elif exclude : <EOL> properties = ( x for x in properties if x [ <NUM_LIT:0> ] not in exclude ) <EOL> field_dict = { } <EOL> for name , p in properties : <EOL> if ignore_hidden and name . startswith ( '<STR_LIT:_>' ) : <EOL> continue <EOL> prop = _resolve_prop ( p ) <EOL> field = converter . convert ( model , mapper , prop , field_args . get ( name ) , hidden_pk ) <EOL> if field is not None : <EOL> field_dict [ name ] = field <EOL> if not only and extra_fields : <EOL> for name , field in iteritems ( extra_fields ) : <EOL> field_dict [ name ] = form . recreate_field ( field ) <EOL> return type ( model . __name__ + '<STR_LIT>' , ( base_class , ) , field_dict ) <EOL> class InlineModelConverter ( InlineModelConverterBase ) : <EOL> """<STR_LIT>""" <EOL> inline_field_list_type = InlineModelFormList <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , session , view , model_converter ) : <EOL> """<STR_LIT>""" <EOL> super ( InlineModelConverter , self ) . __init__ ( view ) <EOL> self . session = session <EOL> self . model_converter = model_converter <EOL> def get_info ( self , p ) : <EOL> info = super ( InlineModelConverter , self ) . get_info ( p ) <EOL> if info is None : <EOL> if hasattr ( p , '<STR_LIT>' ) : <EOL> return self . form_admin_class ( p ) <EOL> else : <EOL> model = getattr ( p , '<STR_LIT>' , None ) <EOL> if model is None : <EOL> raise Exception ( '<STR_LIT>' % repr ( p ) ) <EOL> attrs = dict ( ) <EOL> for attr in dir ( p ) : <EOL> if not attr . startswith ( '<STR_LIT:_>' ) and attr != '<STR_LIT>' : <EOL> attrs [ attr ] = getattr ( p , attr ) <EOL> return self . form_admin_class ( model , ** attrs ) <EOL> info = self . form_admin_class ( model , ** attrs ) <EOL> info . _form_ajax_refs = self . process_ajax_refs ( info ) <EOL> return info <EOL> def process_ajax_refs ( self , info ) : <EOL> refs = getattr ( info , '<STR_LIT>' , None ) <EOL> result = { } <EOL> if refs : <EOL> for name , opts in iteritems ( refs ) : <EOL> new_name = '<STR_LIT>' % ( info . model . __name__ . lower ( ) , name ) <EOL> loader = None <EOL> if isinstance ( opts , dict ) : <EOL> loader = create_ajax_loader ( info . model , self . session , new_name , name , opts ) <EOL> else : <EOL> loader = opts <EOL> result [ name ] = loader <EOL> self . view . _form_ajax_refs [ new_name ] = loader <EOL> return result <EOL> def contribute ( self , model , form_class , inline_model ) : <EOL> """<STR_LIT>""" <EOL> mapper = model . _sa_class_manager . mapper <EOL> info = self . get_info ( inline_model ) <EOL> target_mapper = info . model . _sa_class_manager . mapper <EOL> reverse_prop = None <EOL> for prop in target_mapper . iterate_properties : <EOL> if hasattr ( prop , '<STR_LIT>' ) and prop . direction . name in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> if issubclass ( model , prop . mapper . class_ ) : <EOL> reverse_prop = prop <EOL> break <EOL> else : <EOL> raise Exception ( '<STR_LIT>' % info . model ) <EOL> forward_prop = None <EOL> if prop . direction . name == '<STR_LIT>' : <EOL> candidate = '<STR_LIT>' <EOL> else : <EOL> candidate = '<STR_LIT>' <EOL> for prop in mapper . iterate_properties : <EOL> if hasattr ( prop , '<STR_LIT>' ) and prop . direction . name == candidate : <EOL> if prop . mapper . class_ == target_mapper . class_ : <EOL> forward_prop = prop <EOL> break <EOL> else : <EOL> raise Exception ( '<STR_LIT>' % info . model ) <EOL> ignore = [ reverse_prop . key ] <EOL> if info . form_excluded_columns : <EOL> exclude = ignore + list ( info . form_excluded_columns ) <EOL> else : <EOL> exclude = ignore <EOL> converter = self . model_converter ( self . session , info ) <EOL> child_form = info . get_form ( ) <EOL> if child_form is None : <EOL> child_form = get_form ( info . model , <EOL> converter , <EOL> only = info . form_columns , <EOL> exclude = exclude , <EOL> field_args = info . form_args , <EOL> hidden_pk = True ) <EOL> child_form = info . postprocess_form ( child_form ) <EOL> kwargs = dict ( ) <EOL> label = self . get_label ( info , forward_prop . key ) <EOL> if label : <EOL> kwargs [ '<STR_LIT:label>' ] = label <EOL> if self . view . form_args : <EOL> field_args = self . view . form_args . get ( forward_prop . key , { } ) <EOL> kwargs . update ( ** field_args ) <EOL> setattr ( form_class , <EOL> forward_prop . key , <EOL> self . inline_field_list_type ( child_form , <EOL> self . session , <EOL> info . model , <EOL> reverse_prop . key , <EOL> info , <EOL> ** kwargs ) ) <EOL> return form_class </s>
