class MyView(ModelView): # Disable model creation # can_create = False can_delete = False # Override displayed fields column_exclude_list = [ 'delete_time', 'update_time', 'create_time', 'status' ] column_list = ('email', 'nickname', 'auth') column_labels = {'email': u"邮件", 'nickname': u"头像", 'auth': u"权限"} form_extra_fields = { 'auth': form.Select2Field('权限', choices=[('1', '权限1'), ('2', '权限2')]) } # form_overrides = dict(auth=SelectField) # form_args = dict( # # Pass the choices to the `SelectField` # auth=dict( # choices=[(1, '超级管理员'), (10, '普通管理员'), (100, '普通用户')] # )) def __init__(self, session, **kwargs): # You can pass name add other parameters if you want to super(MyView, self).__init__(User, session, **kwargs)
def conv_String(self, column, field_args, **extra): if hasattr(column.type, 'enums'): field_args['validators'].append(validators.AnyOf( column.type.enums)) field_args['choices'] = [(f, f) for f in column.type.enums] return form.Select2Field(**field_args) if column.nullable: filters = field_args.get('filters', []) filters.append(lambda x: x or None) field_args['filters'] = filters self._string_common(column=column, field_args=field_args, **extra) return fields.StringField(**field_args)
def convert_enum(self, column, field_args, **extra): available_choices = [(f, f) for f in column.type.enums] accepted_values = [key for key, val in available_choices] if column.nullable: field_args['allow_blank'] = column.nullable accepted_values.append(None) filters = field_args.get('filters', []) filters.append(lambda x: x or None) field_args['filters'] = filters field_args['choices'] = available_choices field_args['validators'].append(validators.AnyOf(accepted_values)) field_args['coerce'] = lambda v: v.name if isinstance(v, Enum) else text_type(v) return form.Select2Field(**field_args)
def convert_choice_type(self, column, field_args, **extra): available_choices = [] # choices can either be specified as an enum, or as a list of tuples if isinstance(column.type.choices, EnumMeta): available_choices = [(f.value, f.name) for f in column.type.choices] else: available_choices = column.type.choices accepted_values = [key for key, val in available_choices] if column.nullable: field_args['allow_blank'] = column.nullable accepted_values.append(None) filters = field_args.get('filters', []) filters.append(lambda x: x or None) field_args['filters'] = filters field_args['choices'] = available_choices field_args['validators'].append(validators.AnyOf(accepted_values)) field_args['coerce'] = choice_type_coerce_factory(column.type) return form.Select2Field(**field_args)
def conv_String(self, column, field_args, **extra): if hasattr(column.type, 'enums'): accepted_values = list(column.type.enums) field_args['choices'] = [(f, f) for f in column.type.enums] if column.nullable: field_args['allow_blank'] = column.nullable accepted_values.append(None) field_args['validators'].append(validators.AnyOf(accepted_values)) field_args['coerce'] = lambda v: v.name if isinstance(v, Enum) else text_type(v) return form.Select2Field(**field_args) if column.nullable: filters = field_args.get('filters', []) filters.append(lambda x: x or None) field_args['filters'] = filters self._string_common(column=column, field_args=field_args, **extra) return fields.StringField(**field_args)
def convert(self, model, mapper, name, prop, field_args, hidden_pk): # Properly handle forced fields if isinstance(prop, FieldPlaceholder): return form.recreate_field(prop.field) kwargs = {'validators': [], 'filters': []} if field_args: kwargs.update(field_args) if kwargs['validators']: # Create a copy of the list since we will be modifying it. kwargs['validators'] = list(kwargs['validators']) # Check if it is relation or property if hasattr(prop, 'direction') or is_association_proxy(prop): property_is_association_proxy = is_association_proxy(prop) if property_is_association_proxy: if not hasattr(prop.remote_attr, 'prop'): raise Exception( 'Association proxy referencing another association proxy is not supported.' ) prop = prop.remote_attr.prop return self._convert_relation(name, prop, property_is_association_proxy, kwargs) elif hasattr(prop, 'columns'): # Ignore pk/fk # Check if more than one column mapped to the property if len(prop.columns) > 1: columns = filter_foreign_columns(model.__table__, prop.columns) if len(columns) > 1: warnings.warn( 'Can not convert multiple-column properties (%s.%s)' % (model, prop.key)) return None column = columns[0] else: # Grab column column = prop.columns[0] form_columns = getattr(self.view, 'form_columns', None) or () # Do not display foreign keys - use relations, except when explicitly instructed if column.foreign_keys and prop.key not in form_columns: return None # Only display "real" columns if not isinstance(column, Column): return None unique = False if column.primary_key: if hidden_pk: # If requested to add hidden field, show it return fields.HiddenField() else: # By default, don't show primary keys either # If PK is not explicitly allowed, ignore it if prop.key not in form_columns: return None # Current Unique Validator does not work with multicolumns-pks if not has_multiple_pks(model): kwargs['validators'].append( Unique(self.session, model, column)) unique = True # If field is unique, validate it if column.unique and not unique: kwargs['validators'].append(Unique(self.session, model, column)) optional_types = getattr(self.view, 'form_optional_types', (Boolean, )) if (not column.nullable and not isinstance(column.type, optional_types) and not column.default and not column.server_default): kwargs['validators'].append(validators.InputRequired()) # Apply label and description if it isn't inline form field if self.view.model == mapper.class_: kwargs['label'] = self._get_label(prop.key, kwargs) kwargs['description'] = self._get_description(prop.key, kwargs) # Figure out default value default = getattr(column, 'default', None) value = None if default is not None: value = getattr(default, 'arg', None) if value is not None: if getattr(default, 'is_callable', False): value = lambda: default.arg(None) # noqa: E731 else: if not getattr(default, 'is_scalar', True): value = None if value is not None: kwargs['default'] = value # Check nullable if column.nullable: kwargs['validators'].append(validators.Optional()) # Override field type if necessary override = self._get_field_override(prop.key) if override: return override(**kwargs) # Check choices form_choices = getattr(self.view, 'form_choices', None) if mapper.class_ == self.view.model and form_choices: choices = form_choices.get(prop.key) if choices: return form.Select2Field(choices=choices, allow_blank=column.nullable, **kwargs) # Run converter converter = self.get_converter(column) if converter is None: return None return converter(model=model, mapper=mapper, prop=prop, column=column, field_args=kwargs) return None