class UserForm(form.Form): """создаём форму""" chat_id = fields.IntegerField( 'chat_id', [validators.DataRequired()]) # поле с chat_id в базе group = fields.SelectField('Группа', widget=Select2Widget()) # поле с group в базе notifications = fields.IntegerField('За сколько минут делать напоминания', default=0) # поле с chat_id в базе reminders = InlineFormField(InnerFormWeeks, 'Время напоминаний', default={}) # поле с reminders в базе
def get_edit_form(self): form = self.scaffold_form() form.botid = fields.StringField('机器人', render_kw={'readonly': True}) form.target = fields.StringField('目标', render_kw={'readonly': True}) form.name = fields.StringField('账户名', render_kw={'readonly': True}) form.type = fields.SelectField('类型', coerce=str, choices=get_acttype_choice(), widget=Select2Widget()) form.is_default = fields.BooleanField('缺省账户') return form
def get_edit_form(self): form = self.scaffold_form() # delattr(form, 'target') form.target_type = fields.SelectField( '目标类型', [validators.required(message='目标类型是必填字段')], coerce=str, choices=get_target_type_choice(), widget=Select2Widget()) form.target_account = fields.StringField( '目标账号', [validators.required(message='目标账号是必填字段')]) form.type = fields.SelectField( '类型', [validators.required(message='类型是必填字段')], coerce=str, choices=self.__type_list.items(), widget=Select2Widget()) form.botid = fields.StringField('机器人ID', render_kw={'readonly': True}) def query_factory(): return self.model.find_by_id() return form
class QuerySelectMultipleField(QuerySelectField): """ Very similar to QuerySelectField with the difference that this will display a multiple select. The data property will hold a list with ORM model instances and will be an empty list when no value is selected. If any of the items in the data list or submitted form data cannot be found in the query, this will result in a validation error. """ widget = Select2Widget(multiple=True) def __init__(self, label=None, validators=None, default=None, **kwargs): if default is None: default = [] super(QuerySelectMultipleField, self).__init__(label, validators, default=default, **kwargs) self._invalid_formdata = False def _get_data(self): formdata = self._formdata if formdata is not None: data = [] for pk, obj in self._get_object_list(): if not formdata: break elif pk in formdata: formdata.remove(pk) data.append(obj) if formdata: self._invalid_formdata = True self._set_data(data) return self._data def _set_data(self, data): self._data = data self._formdata = None data = property(_get_data, _set_data) def iter_choices(self): for pk, obj in self._get_object_list(): yield (pk, self.get_label(obj), obj in self.data) def process_formdata(self, valuelist): self._formdata = set(valuelist) def pre_validate(self, form): if self._invalid_formdata: raise ValidationError(self.gettext(u'Not a valid choice')) elif self.data: obj_list = list(x[1] for x in self._get_object_list()) for v in self.data: if v not in obj_list: raise ValidationError(self.gettext(u'Not a valid choice'))
class AreaModelView(ModelView): column_hide_backrefs = False form_extra_fields = { 'ancestor': QuerySelectField( label='Ancestor', query_factory=lambda: Area.query.all(), widget=Select2Widget() ) } def on_model_change(self, form, model, is_created): if not is_created and form.ancestor.data.id == model.id: model.ancestor_id = 1
class IdACLModelView(ACLModelViewMixin, ModelView): """ModelView for the ID ACLs.""" column_formatters = dict( # record_str=link_record ) column_details_list = ( 'id', 'name', 'record_str', 'schemas', 'created', 'updated', 'originator', 'priority', 'operation') column_list = ('id', 'name', 'operation', 'record_str', 'priority', 'created', 'updated', 'originator') column_labels = dict( id=_('ACL ID'), record_str=_('Record') ) column_filters = ('created', 'updated',) column_searchable_list = ('name',) column_default_sort = 'name' form_base_class = FlaskForm form_columns = ('name', 'priority', 'record_id', 'schemas', 'operation', 'actors') form_args = dict( ) page_size = 25 form_extra_fields = { 'schemas': sqla.fields.QuerySelectMultipleField( label='Schemas', query_factory=schemas_choices, widget=Select2Widget(multiple=True), get_pk=lambda x: x, ) } def validate_form(self, form): """Validator that fills in schema from the record if not yet already filled.""" if not super().validate_form(form): return False if hasattr(form, 'schemas'): schemas = form.schemas.data if not schemas: record_id = form.record_id.data try: rec = Record.get_record(record_id) except: form.schemas.errors.append('No schemas defined and the record with the given does not exist yet') return False form.schemas.data = [ rec.get('$schema', '') ] return True
class UsersForm(form.Form): email = fields.StringField('用户邮箱', validators=[DataRequired('邮箱不能为空'), Email('邮箱格式不正确')]) username = fields.StringField('昵称', validators=[DataRequired('昵称不能为空')]) is_active = fields.BooleanField('激活状态') is_disabled = fields.BooleanField('禁用') is_admin = fields.BooleanField('超级管理员') vip = fields.IntegerField('VIP等级') avatar = fields.StringField('头像') coin = fields.IntegerField('金币') description = fields.TextAreaField('签名') city = fields.StringField('城市') renzheng = fields.StringField('认证信息') role_ids = fields.SelectMultipleField('角色', widget=Select2Widget(multiple=True)) form_columns = ('email', 'username', 'is_active', 'is_admin', 'avatar', 'coin', 'description', 'city')
def get_create_form(self): form = self.scaffold_form() delattr(form, 'target') form.target_type = fields.SelectField('目标类型', coerce=str, choices=get_target_type_choice(), widget=Select2Widget()) form.target_account = fields.StringField( '目标账号', [validators.required(message='目标账号是必填字段')]) form.type = fields.SelectField( '类型', [validators.required(message='类型是必填字段')], coerce=str, choices=self.__type_list.items(), widget=Select2Widget()) def query_factory(): from flask_login import current_user from common.bot import BotAssign return [ r.botid for r in BotAssign.find_by_user(current_user.username) ] def get_pk(obj): return obj def get_label(obj): return Bot.find(obj).name from wtforms.ext.sqlalchemy.fields import QuerySelectField form.botid = QuerySelectField( '机器人', [validators.required(message='机器人是必填字段')], query_factory=query_factory, get_label=get_label, get_pk=get_pk, widget=Select2Widget()) return form
class GroupsForm(form.Form): choices_institute = [ 'Аспирантура', 'Институт авиамашиностроения и транспорта', 'Институт архитектуры, строительства и дизайна', 'Институт высоких технологий', 'Институт заочно-вечернего обучения', 'Институт информационных технологий и анализа данных', 'Институт недропользования', 'Институт экономики, управления и права', 'Институт энергетики' ] choices_course = [ '1 курс', '2 курс', '3 курс', '4 курс', '5 курс', '6 курс' ] name = fields.SelectField('Группа', widget=Select2Widget()) institute = fields.SelectField('Институт', choices=choices_institute) link = fields.StringField('Ссылка', [validators.DataRequired()]) course = fields.SelectField('Курс', choices=choices_course)
class ElasticsearchACLModelView(ACLModelViewMixin, ModelView): """ModelView for the elasticsearch ACLs.""" column_formatters = dict( ) column_details_list = ( 'id', 'name', 'record_selector', 'created', 'updated', 'originator', 'priority', 'operation') column_list = ( 'id', 'name', 'schemas', 'operation', 'record_selector', 'priority', 'created', 'updated', 'originator') column_labels = dict( id=_('ACL ID'), database_operations=_('Operations') ) column_filters = ('created', 'updated',) column_searchable_list = ('name',) column_default_sort = 'name' form_base_class = FlaskForm form_columns = ('name', 'priority', 'schemas', 'operation', 'record_selector', 'actors') form_args = dict( ) page_size = 25 form_extra_fields = { 'schemas': sqla.fields.QuerySelectMultipleField( label='Schemas', query_factory=schemas_choices, widget=Select2Widget(multiple=True), get_pk=lambda x: x, ) } def validate_record_selector(self, form, field): """Checks that the record selector is valid and we can use it to perform query in elasticsearch index.""" schemas = form.schemas.data record_selector = field.data if not record_selector: raise StopValidation( 'Record selector must not be empty. If you want to match all resources, use {"match_all": {}}') try: for index in schemas: current_search_client.search( index=index, size=0, body={ 'query': record_selector } ) except Exception as e: raise StopValidation(str(e))
def get_create_form(self): form = self.scaffold_form() def query_factory(): return [r.id for r in Bot.findall()] def get_pk(obj): return obj def get_label(obj): return Bot.find(obj).name from wtforms.ext.sqlalchemy.fields import QuerySelectField form.botid = QuerySelectField( '机器人', [validators.required(message='机器人是必填字段')], query_factory=query_factory, get_label=get_label, get_pk=get_pk, widget=Select2Widget()) return form
class ResetPasswordTokenForm(form.Form): user_uid = fields.SelectField('User', widget=Select2Widget())
class CatalogsForm(form.Form): name = fields.StringField('栏目名称') moderator_id = fields.SelectField('版主', widget=Select2Widget()) sort_key = fields.IntegerField('排序', default=0) form_columns = ('name', 'sort_key')
class MyPersonView(MyModelView): def get_query(self): if login.current_user.has_role('posel2'): return self.session.query( self.model).filter(self.model.hostel_id == 1) elif login.current_user.has_role('posel3'): return self.session.query( self.model).filter(self.model.hostel_id == 2) elif login.current_user.has_role('posel4'): return self.session.query( self.model).filter(self.model.hostel_id == 3) else: return self.session.query(self.model) def get_count_query(self): if login.current_user.has_role('posel2'): return self.session.query(func.count('*')).select_from( self.model).filter(self.model.hostel_id == 1) elif login.current_user.has_role('posel3'): return self.session.query(func.count('*')).select_from( self.model).filter(self.model.hostel_id == 2) elif login.current_user.has_role('posel4'): return self.session.query(func.count('*')).select_from( self.model).filter(self.model.hostel_id == 3) else: return self.session.query(func.count('*')).select_from(self.model) @action('approve', 'Выселить', 'Вы уверены, что хотите выселить?') def action_approve(self, ids): try: query = models.Person.query.filter(models.Person.id.in_(ids)) count = 0 for user in query.all(): try: db.session.add(models.Person_old(user)) models.Room_free.query.filter_by( room_id=user.room).first().places += 1 db.session.commit() except Exception: print('error') finally: db.session.delete(user) db.session.commit() count += 1 flash('Выселено', '%s users were successfully approved.' % count) except Exception as ex: if not self.handle_view_exception(ex): raise column_exclude_list = ('id', 'parents', 'index', 'note', 'invite', 'phone_number_parent', 'street', 'passport', 'department', 'group', 'form_of_education', 'hostel_id', 'room_id', 'birthday', 'district', 'email', 'start_date', 'end_date') column_searchable_list = ('first_name', 'last_name') edit_modal = True create_modal = True can_export = True export_types = ['xlsx'] column_export_exclude_list = ['person_room'] column_editable_list = ['first_name', 'last_name'] column_labels = { 'first_name': 'Фамилия', 'last_name': 'Имя', 'middle_name': 'Отчество' } column_auto_select_related = True form_extra_fields = { 'person_room': QuerySelectField(label='Комната', query_factory=lambda: models.Room.query.filter_by( hostel_id=1).all() if login.current_user.has_role('posel2') else models. Room.query.filter_by(hostel_id=2).all() if login.current_user.has_role('posel3') else models. Room.query.filter_by(hostel_id=4).all() if login.current_user.has_role( 'posel4') else models.Room.query.all(), widget=Select2Widget()) }
class InstitutesForm(form.Form): """создаём форму""" name = fields.SelectField('Институт', widget=Select2Widget()) link = fields.StringField('Ссылка', [validators.DataRequired()])
class OrganizationAdmin(ModelViewWithAccess): from psi.app.views.formatter import organization_formatter uos = 'UPDATE ' + Organization.__tablename__ + ' SET' @property def can_create(self): return is_super_admin() @property def can_delete(self): return is_super_admin() def get_query(self): return self.get_query_based_on_user(self.model) def get_count_query(self): return self.get_query_based_on_user(func.count('*')) def get_query_based_on_user(self, return_query): all_ids = Organization.get_children_self_ids(current_user.organization) return (self.session.query(return_query).filter( self.model.id.in_(all_ids)) if not is_super_admin() else self.session.query(return_query)) column_list = ( 'id', 'name', 'description', 'type', 'parent', 'immediate_children', ) column_sortable_list = ('id', 'name', 'description', 'type') column_searchable_list = ('name', 'description', 'parent.name', 'parent.description', 'lft', 'rgt', 'type.code', 'type.display') column_labels = dict( id=lazy_gettext('id'), name=lazy_gettext('Name'), description=lazy_gettext('Description'), parent=lazy_gettext('Parent Organization'), lft=lazy_gettext('Left'), rgt=lazy_gettext('Right'), type=lazy_gettext('Type'), immediate_children=lazy_gettext('Immediate Children'), all_children=lazy_gettext('All Children'), ) form_args = dict(type=dict(query_factory=Organization.type_filter)) column_formatters = { 'immediate_children': organization_formatter, 'all_children': organization_formatter, 'parent': organization_formatter } column_editable_list = ('description', ) form_excluded_columns = ( 'lft', 'rgt', ) form_extra_fields = { 'parent': QuerySelectField( label=lazy_gettext('Parent Organization'), query_factory=lambda: Organization.query.all(), widget=Select2Widget(), allow_blank=False, ) } def edit_form(self, obj=None): form = super(OrganizationAdmin, self).edit_form(obj) # form.parent._data_list is None at this moment, so it's not feasible to change the _data_list attribute directly here # to set the query_factory function is the right way to implement a filter. form.parent.query_factory = partial(Organization.children_remover, obj) # For root organization, allow blank if is_root_organization(obj): form.parent.allow_blank = True # Does not allow to change type for root organization delattr(form, "type") return form column_details_list = ('id', 'name', 'description', 'lft', 'rgt', 'parent', 'immediate_children', 'all_children') def after_model_change(self, form, model, is_created): """ :param form: form object from the UI :param model: model, when on after_model_change, it has got id field and necessary default value from DB. :param is_created: True if model was created, False if model was updated :return: None Update left and right field of all impacted organization vai raw sql, and also update left and right of the newly added organization to it's parent's current right and current right + 1 """ from sqlalchemy import text from psi.app.service import Info db = Info.get_db() str_id = getattr(form, "parent").raw_data[0] int_id = int( str_id) if str_id is not None and str_id != u"__None" and len( str_id) > 0 else None parent = db.session.query(Organization).get( int_id) if int_id is not None else None if is_created: # New create # update all exiting node with right and left bigger than current parent's right - 1 if parent is not None: model.parent = parent elif parent is not None: # Changing parent of a subtree or leaf. # Refer to http://stackoverflow.com/questions/889527/move-node-in-nested-set for detail. lft = model.lft rgt = model.rgt parent_rgt = parent.rgt ts = int(rgt - lft + 1) # step 1: temporary "remove" moving node, change lft and right to negative integer # step 2: decrease left and/or right position values of currently 'lower' items (and parents) # step 3: increase left and/or right position values of future 'lower' items (and parents) # step 4: move node (ant it's subtree) and update it's parent item id c = parent_rgt - ts if parent_rgt > rgt else parent_rgt d = parent_rgt - rgt - 1 if parent_rgt > rgt else parent_rgt - rgt - 1 + ts sql = [ '{u} lft = 0 - lft, rgt = 0 - rgt where lft >= {lft} and rgt <={rgt}' .format(u=self.uos, lft=lft, rgt=rgt), '{u} lft = lft - {ts} where lft > {rgt}'.format(u=self.uos, ts=ts, rgt=rgt), '{u} rgt = rgt - {ts} where rgt > {rgt}'.format(u=self.uos, ts=ts, rgt=rgt), '{u} lft = lft + {ts} where lft >= {c}'.format(ts=ts, c=c, u=self.uos), '{u} rgt = rgt + {ts} where rgt >= {c}'.format(ts=ts, c=c, u=self.uos), '{u} lft = 0-lft+{d}, rgt = 0-rgt + {d} where lft <= 0-{lft} and rgt >= 0-{rgt}' .format(d=d, lft=lft, rgt=rgt, u=self.uos) ] for s in sql: db.engine.execute(text(s)) db.session.commit() def on_model_change(self, form, model, is_created): """Check whether the parent organization or child organization is same as the value being edited""" super(OrganizationAdmin, self).on_model_change(form, model, is_created) if (not is_root_organization(model)) and ( getattr(form, "parent") is None or getattr(form, "parent")._data is None): raise ValidationError( gettext( 'Please specify parent organization(creation of top level organization not allowed)' )) CycleReferenceValidator.validate(form, model, object_type='Organization', parent='parent', children='all_children', is_created=is_created) def on_model_delete(self, model): """ Validate model with child organization should not be deleted :param model: The model to delete :return: None """ if len(model.all_children) > 0: raise ValidationError( gettext( 'Can not delete an organization with child organisation exists' )) def after_model_delete(self, model): """ Adjust left and right value for organizations in DB after deleting the model. :param model: Model to delete :return: None """ from sqlalchemy import text from psi.app.service import Info db = Info.get_db() width = model.rgt - model.lft + 1 sql = text( "{u} rgt = rgt-{w} WHERE rgt > {rgt};{u} lft = lft-{w} WHERE lft > {lft}" .format(rgt=model.rgt, lft=model.lft, w=width, u=self.uos)) db.engine.execute(sql) db.session.commit()
class ScheduleForm(form.Form): group = fields.SelectField('Группа', widget=Select2Widget()) schedule = InlineFieldList(InlineFormField(InnerFormDays), 'Расписание')
class RolesForm(form.Form): name = fields.StringField('角色名', validators=[DataRequired('角色名不能为空')]) permissions = fields.SelectMultipleField('权限', widget=Select2Widget(multiple=True), validators=[DataRequired('权限不能为空')])
class EmailConfirmationTokenForm(form.Form): user_uid = fields.SelectField('User', widget=Select2Widget())
class CurriculumForm(form.Form): name = fields.StringField('curriculum') school = fields.SelectField('School', widget=Select2Widget()) # Form list Course = InlineFieldList(InlineFormField(CourseForm))
class TweetForm(Form): name = fields.StringField('Name') user_id = fields.SelectField('User', widget=Select2Widget()) text = fields.StringField('Text') testie = fields.BooleanField('Test')
class NotificationForm(form.Form): user_uid = fields.SelectField('User', widget=Select2Widget())
class QuerySelectField(SelectFieldBase): """ Will display a select drop-down field to choose between ORM results in a sqlalchemy `Query`. The `data` property actually will store/keep an ORM model instance, not the ID. Submitting a choice which is not in the query will result in a validation error. This field only works for queries on models whose primary key column(s) have a consistent string representation. This means it mostly only works for those composed of string, unicode, and integer types. For the most part, the primary keys will be auto-detected from the model, alternately pass a one-argument callable to `get_pk` which can return a unique comparable key. The `query` property on the field can be set from within a view to assign a query per-instance to the field. If the property is not set, the `query_factory` callable passed to the field constructor will be called to obtain a query. Specify `get_label` to customize the label associated with each option. If a string, this is the name of an attribute on the model object to use as the label text. If a one-argument callable, this callable will be passed model instance and expected to return the label text. Otherwise, the model object's `__str__` or `__unicode__` will be used. If `allow_blank` is set to `True`, then a blank choice will be added to the top of the list. Selecting this choice will result in the `data` property being `None`. The label for this blank choice can be set by specifying the `blank_text` parameter. """ widget = Select2Widget() def __init__(self, label=None, validators=None, query_factory=None, get_pk=None, get_label=None, allow_blank=False, blank_text=u'', **kwargs): super(QuerySelectField, self).__init__(label, validators, **kwargs) self.query_factory = query_factory if get_pk is None: if not has_identity_key: raise Exception(u'The sqlalchemy identity_key function could not be imported.') self.get_pk = get_pk_from_identity else: self.get_pk = get_pk if get_label is None: self.get_label = lambda x: x elif isinstance(get_label, string_types): self.get_label = operator.attrgetter(get_label) else: self.get_label = get_label self.allow_blank = allow_blank self.blank_text = blank_text self.query = None self._object_list = None def _get_data(self): if self._formdata is not None: for pk, obj in self._get_object_list(): if pk == self._formdata: self._set_data(obj) break return self._data def _set_data(self, data): self._data = data self._formdata = None data = property(_get_data, _set_data) def _get_object_list(self): if self._object_list is None: query = self.query or self.query_factory() get_pk = self.get_pk self._object_list = [(text_type(get_pk(obj)), obj) for obj in query] return self._object_list def iter_choices(self): if self.allow_blank: yield (u'__None', self.blank_text, self.data is None) for pk, obj in self._get_object_list(): yield (pk, self.get_label(obj), obj == self.data) def process_formdata(self, valuelist): if valuelist: if self.allow_blank and valuelist[0] == u'__None': self.data = None else: self._data = None self._formdata = valuelist[0] def pre_validate(self, form): if not self.allow_blank or self.data is not None: for pk, obj in self._get_object_list(): if self.data == obj: break else: raise ValidationError(self.gettext(u'Not a valid choice'))
class ClassForm(form.Form): name = fields.StringField('name') curriculum = fields.SelectField('curriculum', widget=Select2Widget()) school = fields.SelectField('school', widget=Select2Widget()) order = fields.StringField('order')