class CreateUserForm(Form): # TODO: NAME字段格式检查的中文支持 next_page = HiddenField() email = TextField(u'Email', description=u'Unique', validators=[Required(message=u'Email is required'), Email(message=u'Incorrect email format'), Unique(User, User.email, message=u'The current email is already in use')]) username = TextField(u'Username', description=u'Unique', validators=[Required(message=u'Username is required'), Regexp(u'^[a-zA-Z0-9\_\-\.]{5,20}$', message=u'Incorrect username format'), Unique(User, User.username, message=u'The current name is already in use')]) name = TextField(u'Name', description=u'Unique', validators=[Required(message=u'Name is required'), Regexp(u'^[a-zA-Z0-9\_\-\.\ ]{1,20}$', message=u'Incorrect name format'), Unique(User, User.name, message=u'The current name is already in use')]) weixin = TextField(u'Weixin OpenID', description=u'Unique, Using the command <code>openid</code> get in WeiXin', validators=[Optional(), Unique(User, User.weixin, message=u'The current weixin OpenID is already in use')]) groups = QuerySelectMultipleField(u'Group', description=u'Multiple Choice', query_factory=Group.query.all, get_label='desc', validators=[Required(message=u'Group is required')]) password = TextField(u'Password', description=u'At least five characters', validators=[Required(message=u'Password is required'), Regexp(u'^.{5,20}$', message=u'Password are at least five chars')]) status = BooleanField(u'Status', description=u'Check to enable this user') submit = SubmitField(u'Submit', id='submit')
class SignupForm(BaseForm): username = TextField( _('Username'), validators=[ DataRequired(), Length(min=3, max=20), Regexp(r'^[a-z0-9A-Z]+$') ], description=_('English Characters Only.'), ) email = EmailField(_('Email'), validators=[DataRequired(), Email()]) password = PasswordField(_('Password'), validators=[DataRequired()]) def validate_username(self, field): data = field.data.lower() if data in RESERVED_WORDS: raise ValueError(_('This name is a reserved name.')) if data in current_app.config.get('RESERVED_WORDS', []): raise ValueError(_('This name is a reserved name.')) if Account.query.filter_by(username=data).count(): raise ValueError(_('This name has been registered.')) def validate_email(self, field): if Account.query.filter_by(email=field.data.lower()).count(): raise ValueError(_('This email has been registered.')) def save(self, role=None): user = Account(**self.data) if role: user.role = role user.save() return user
class DesktopReleaseForm(ReleaseForm): partials = StringField( 'Partial versions:', validators=[ Regexp(PARTIAL_VERSIONS_REGEX, message='Invalid partials format.') ], filters=[collapseSpaces], ) promptWaitTime = NullableIntegerField('Update prompt wait time:') l10nChangesets = PlainChangesetsField( 'L10n Changesets:', validators=[DataRequired('L10n Changesets are required.')]) def addSuggestions(self): ReleaseForm.addSuggestions(self) table = getReleaseTable(self.product.data) recentReleases = table.getRecentShipped() seenVersions = [] partials = defaultdict(list) # The UI will suggest any versions which are on the same branch as # the one given, but only the highest build number for that version. # One exception is Firefox RC builds (version X.0), which should be added # to the list of betas for release in reversed(recentReleases): if release.version not in seenVersions: partials[release.branch].append( '%sbuild%d' % (release.version, release.buildNumber)) seenVersions.append(release.version) # here's the exception if release.product == 'firefox' and \ release.branch == 'releases/mozilla-release' and \ re.match('^\d+\.0$', release.version): partials['releases/mozilla-beta'].append( '%sbuild%d' % (release.version, release.buildNumber)) self.partials.suggestions = json.dumps(partials)
class ChangePasswordForm(Form): # TODO: NAME字段格式检查的中文支持 next_page = HiddenField() id = IntegerField(widget=HiddenInput()) now_password = PasswordField(u'Password') new_password = PasswordField( u'New Password', description=u'At least eight characters', validators=[ Optional(), Regexp(u'(^.{8,20}$)|(^$)', message=u'Password are at least eight chars'), Depend('now_password', message=u'Password is required when changing password') ]) confirm_password = PasswordField( u'Confirm Password', description=u'Re-enter the new password', validators=[ Optional(), EqualTo('new_password', message=u'New passwords must be the same') ]) submit = SubmitField(u'Submit', id='submit')
class EditSettingForm(Form): # TODO: NAME字段格式检查的中文支持 next_page = HiddenField() id = IntegerField(widget=HiddenInput()) email = TextField(u'Email', validators=[UnChanged()]) username = TextField(u'Username', validators=[UnChanged()]) name = TextField(u'Name', description=u'Unique', validators=[ Required(message=u'Name is required'), Regexp(u'^[a-zA-Z0-9\_\-\.\ ]{1,20}$', message=u'Incorrect name format'), Unique(User, User.name, message=u'The current name is already in use') ]) weixin = TextField( u'Weixin OpenID', description= u'Unique, Using the command <code>openid</code> get in WeiXin', validators=[ Optional(), Unique(User, User.weixin, message=u'The current weixin OpenID is already in use') ]) submit = SubmitField(u'Submit', id='submit')
class UserRegForm(Form): name = TextField( u"用户名", validators=[Required(), Length(min=3, max=32), Regexp(re_username)]) email = TextField(u'Email', validators=[Required(), Email()]) gender = RadioField(u'性别', coerce=int, choices=[(0, u'男'), (1, u'女')], default=0, widget=BSListWidget()) password = PasswordField(u'密码', validators=[ Required(), Length(min=5, max=60), EqualTo('confirm', message='Passwords must match') ]) confirm = PasswordField(u'确认密码', validators=[Required(), Length(min=5, max=60)]) def validate_name(form, field): name = field.data.lower() if name in reserved_words: raise ValidationError(u'用户名不能为系统保留字') user = User.query.filter(User.username == field.data).first() if user: raise ValidationError(u'该用户名已被注册') def validate_email(form, field): user = User.query.filter(User.email == field.data).first() if user: raise ValidationError(u'该email已被注册')
class ChangeUsernameForm(Form): username = TextField("New Username", validators=[ Required(), Regexp("[0-9a-zA-Z\-_]", message = "The username contains invalid characters. Only use alphanumeric characters, dashes and underscores."), Not(UsernameExists(), message = "That username already exists."), Length(min = 3, max = 32, message="You have to enter a username of 3 to 32 characters length.")]) password = PasswordField("Current Password", validators=[PasswordValidator()])
class DesktopReleaseForm(ReleaseForm): partials = StringField( 'Partial versions:', validators=[ Regexp(PARTIAL_VERSIONS_REGEX, message='Invalid partials format.') ], filters=[collapseSpaces], ) promptWaitTime = NullableIntegerField('Update prompt wait time:') l10nChangesets = PlainChangesetsField( 'L10n Changesets:', validators=[DataRequired('L10n Changesets are required.')]) def addSuggestions(self): ReleaseForm.addSuggestions(self) table = getReleaseTable(self.product.data) recentReleases = table.getRecentShipped() seenVersions = [] partials = {} # The UI will suggest any versions which are on the same branch as # the one given, but only the highest build number for that version. for release in reversed(recentReleases): if release.branch not in partials: partials[release.branch] = [] if release.version not in seenVersions: partials[release.branch].append( '%sbuild%d' % (release.version, release.buildNumber)) seenVersions.append(release.version) self.partials.suggestions = json.dumps(partials)
class URLForm(Form): url = TextField( 'URL', [Required(), Length(max=255), URL()], widget=XXLargeTextInput()) slug = TextField('Slug', [Optional(), Length(max=30), Regexp(RE_SLUG)], widget=TextInput()) submit = SubmitField('shorten')
class SignupForm(Form): username = StringField('Username', validators=[ DataRequired(), Regexp('^[A-Za-z0-9\-_]+$', message='Only alphabets, numbers, hyphen, and underscore are allowed.'), Unique(lambda: db.session, User, User.username) ]) password = PasswordField('Password', validators=[DataRequired()]) password_confirmation = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password', 'Password confirmation is different from password.') ])
class RegistrationForm(Form): username = TextField("Username", validators=[ Required(), Regexp("[0-9a-zA-Z\-_]", message = "The username contains invalid characters. Only use alphanumeric characters, dashes and underscores."), Not(UsernameExists(), message = "That username already exists."), Length(min = 3, max = 32, message="You have to enter a username of 3 to 32 characters length.")]) password = PasswordField("Password", validators=[Length(min = 6, message = "Please enter a password of at least 6 characters.")]) password2 = PasswordField("Password, again", validators=[EqualTo("password", "Passwords do not match.")]) email = EmailField("Email Address", validators=[ Required(), Not(EmailExists(), message = "That email address is already in use."), EmailValidator(message = "The email address you entered is invalid.")])
class RegistrationForm(Form): email = fields.TextField('Email Address', validators=[Required(), Email(), Regexp('[^@]+@[^@]+[fsu]+\.[edu]+')]) consent = fields.BooleanField(validators=[Required()]) password = fields.PasswordField('New Password', [ validators.Required(), validators.Length(min=8, max=20), validators.EqualTo('confirm', message='Passwords must match') ]) confirm = fields.PasswordField(validators=[Required()]) def validate_email(self, field): if db.session.query(User).filter_by(email=self.email.data).count() > 0: raise validators.ValidationError('Duplicate email')
class UserForm(SettingForm): username = TextField( _('Username'), validators=[ DataRequired(), Length(min=3, max=20), Regexp(r'^[a-z0-9A-Z]+$') ], description=_('English Characters Only.'), ) email = EmailField(_('Email'), validators=[DataRequired(), Email()]) role = SelectField( _('Role'), choices=[('spam', _('Spam')), ('user', _('User')), ('staff', _('Staff')), ('admin', _('Admin'))], default='user', )
class UserRegistrationForm(Form): username = TextField("Create a Username...", validators=[ Required(message='Username required'), Regexp('^[a-zA-Z0-9_.-]+$', message="Username contains invalid characters"), Length(min=2, max=18, message="Username must be between 2 and 18 characters"), does_not_have_bad_words]) email = TextField("Email Address:", validators=[ Required(message='Email required'), Email(message="Invalid email address"), email_is_unique]) password = PasswordField("Password", validators=[ Required(message='Password required')]) """
class SettingsForm(Form): username = TextField( u'用户名', validators=[Required(), Length(min=4, max=32), Regexp(re_username)]) #nickname = TextField(u'昵称', validators=[Optional(), Length(max=32)]) city = TextField(u'城市', validators=[Optional(), Length(max=40)]) province = TextField(u'省份', validators=[Optional(), Length(max=40)]) birthday = DateField(u'出生年月日', validators=[Optional()], widget=DatePickerWidget(), default=datetime.date(1990, 1, 1)) blog = TextField(u'博客', validators=[Optional(), URL(), Length(max=100)]) descp = TextAreaField(u'个人介绍', validators=[Optional(), Length(max=500)]) signature = TextAreaField(u'签名', validators=[Optional(), Length(max=200)]) realname = TextField(u'真实姓名', validators=[Optional(), Length(max=80)]) idcard = TextField(u'身份证', validators=[Optional(), Length(max=32)])
class EditProfileForm(Form): username = TextField("Username", validators=[ Regexp('^[a-zA-Z0-9_.-]+$', message="Username contains invalid characters"), Length(min=2, max=16, message="Username must be between 2 and 16 characters"), username_same_or_exists, does_not_have_bad_words]) email = TextField("Email Address", validators=[ Required(message='Email required'), Email(message="Invalid email address")]) password = PasswordField("Change Password", validators=[ Length(min=4, max=32, message="Username must be between 2 and 16 characters"), EqualTo('password2', message='Passwords must match'), Optional()]) password2 = PasswordField("Repeat password", validators=[Optional()])
class IDCForm(Form): next_page = HiddenField() id = IntegerField(widget=HiddenInput()) name = TextField(u'Name', validators=[ Required(message=u'Name is required'), Regexp(u'^[a-zA-Z0-9\_\-\.]{3,20}$', message=u'Incorrect name format') ]) desc = TextField(u'Description', validators=[Required(message=u'Description is required')]) operators = TextField( u'Operators', validators=[Required(message=u'Operators is required')]) address = TextField(u'Address', validators=[Required(message=u'Address is required')]) submit = SubmitField(u'Submit', id='submit')
class KioskUserForm(Form): username = TextField(validators=[ Required(message='Username required'), Regexp('^[a-zA-Z0-9_.-]+$', message="Username contains invalid characters"), Length(min=2, max=16, message="Username must be between 2 and 16 characters"), does_not_have_bad_words ]) phonenumber = TextField(validators=[validate_phonenumber, Optional()]) def get_phone(self): has_phone = len(self.phonenumber.data) == 10 return self.phonenumber.data if has_phone else None def to_user(self): return User(username=self.username.data, phoneNumber=self.phonenumber.data, origin="kiosk")
class IpmiConfigForm(Form): next_page = HiddenField() id = IntegerField(widget=HiddenInput()) name = TextField(u'Name', description=u'Ipmi Config name. Unique', validators=[Required(message=u'Name is required'), Regexp(u'^[a-zA-Z0-9\_\-\.\ ]{1,20}$', message=u'Incorrect name format'), Unique(IpmiConfig, IpmiConfig.name, message=u'The current name is already in use')]) desc = TextField(u'Description', validators=[Required(message=u'Description is required')]) username = TextField(u'Username', default=u'root', validators=[Required(message=u'Username is required')]) password = TextField(u'Password', validators=[Required(message=u'Password is required')]) interface = BooleanField(u'IPMI Interface:', description=u'Select to use <code>lanplus</code> interface, default is <code>lan</code>.') groups = QuerySelectMultipleField(u'Group', description=u'Multiple Choice', query_factory=Group.query.all, get_label='desc', validators=[Required(message=u'Group is required')]) submit = SubmitField(u'Submit', id='submit')
class FabFileForm(Form): script_desc = u'''作为shell中的 <code>$</code> 内部变量的扩展,模板还支持外部变量。\ <code>{{</code> 和 <code>}}</code> 作为外部变量的定界符,此类变量会依据变量文件中的同名赋值定义进行替换, \ 同时标准错误输出以及标准输出中匹配到<code>BD:\w+?:EOF</code>的字符串可以作为返回结果保存。如: <code>device=eth1; echo "IPADDR={{address}}" >> ~/ifcfg-$device</code>''' next_page = HiddenField() id = IntegerField(widget=HiddenInput()) name = TextField(u'Name', description=u'Fabfile name. Unique', validators=[Required(message=u'Name is required'), Regexp(u'^[a-zA-Z0-9\_]{5,50}$', message=u'Incorrect name format'), Unique(FabFile, FabFile.name, message=u'The current name is already in use')]) desc = TextField(u'Description', validators=[Required(message=u'Description is required')]) script = TextAreaField(u'Fabfile', description=u'Fabric\'s fabfile') groups = QuerySelectMultipleField(u'Group', description=u'Multiple Choice', query_factory=Group.query.all, get_label='desc', validators=[Required(message=u'Group is required')]) submit = SubmitField(u'Submit', id='submit')
class SshConfigForm(Form): next_page = HiddenField() id = IntegerField(widget=HiddenInput()) name = TextField(u'Name', description=u'Ssh Config name. Unique', validators=[Required(message=u'Name is required'), Regexp(u'^[a-zA-Z0-9\_\-\.\ ]{1,20}$', message=u'Incorrect name format'), Unique(SshConfig, SshConfig.name, message=u'The current name is already in use')]) desc = TextField(u'Description', validators=[Required(message=u'Description is required')]) port = IntegerField(u'Port', default=22, validators=[Required(message=u'Port is required')]) username = TextField(u'Username', default=u'root', validators=[Required(message=u'Username is required')]) password = TextField(u'Password', validators=[Required(message=u'Password is required')]) private_key = TextField(u'Private Key:', description=u'Private filename in <code>PRIVATE_KEY_PATH</code>') groups = QuerySelectMultipleField(u'Group', description=u'Multiple Choice', query_factory=Group.query.all, get_label='desc', validators=[Required(message=u'Group is required')]) submit = SubmitField(u'Submit', id='submit')
class ReleaseForm(Form): version = StringField('Version:', validators=[ Regexp(ANY_VERSION_REGEX, message='Invalid version format.') ]) buildNumber = IntegerField( 'Build Number:', validators=[DataRequired('Build number is required.')]) branch = StringField('Branch:', validators=[DataRequired('Branch is required')]) mozillaRevision = StringField('Mozilla Revision:') dashboardCheck = BooleanField('Dashboard check?', default=False) mozillaRelbranch = StringField('Mozilla Relbranch:', filters=[noneFilter]) comment = TextAreaField('Extra information to release-drivers:') description = TextAreaField('Description:') isSecurityDriven = BooleanField('Is a security driven release?', default=False) mh_changeset = StringField('Mozharness Revision:') def __init__(self, suggest=True, *args, **kwargs): Form.__init__(self, *args, **kwargs) if suggest: self.addSuggestions() def validate(self, *args, **kwargs): valid = Form.validate(self, *args, **kwargs) # If a relbranch has been passed revision is ignored. if self.mozillaRelbranch.data: self.mozillaRevision.data = self.mozillaRelbranch.data # However, if a relbranch hasn't been passed, revision is required. else: if not self.mozillaRevision.data: valid = False self.errors['mozillaRevision'] = [ 'Mozilla revision is required' ] return valid def addSuggestions(self): table = getReleaseTable(self.product.data) recentReleases = table.getRecent() # Before we make any suggestions we need to do some preprocessing of # the data to get it into useful structures. Specifically, we need a # set containing all of the recent versions, and a dict that associates # them with the branch they were built on. recentVersions = set() recentBranches = defaultdict(list) for release in recentReleases: recentVersions.add(release.version) recentBranches[release.branch].append(LooseVersion( release.version)) # Now that we have the data in the format we want it in we can start # making suggestions. suggestedVersions = set() buildNumbers = {} # This wrapper method is used to centralize the build number suggestion # logic in one place, because there's more than one spot below that # adds a version suggestion. def addVersionSuggestion(version): suggestedVersions.add(version) # We want the UI to be able to automatically set build number # to the next available one for whatever version is entered. # To make this work we need to tell it what the next available # one is for all existing versions. We don't need to add versions # that are on build1, because it uses that as the default. maxBuildNumber = table.getMaxBuildNumber(version) if maxBuildNumber: buildNumbers[version] = maxBuildNumber + 1 else: buildNumbers[version] = 1 # Every version we see will have its potential next versions # suggested, except if we already have that version. # Note that we don't look through the entire table for every # version (because that could be expensive) but any versions # which are suggested and have already happened should be in # 'recentVersions', so it's unlikely we'll be suggesting # something that has already happened. for version in recentVersions: for v in getPossibleNextVersions(version): if v not in recentVersions: addVersionSuggestion(v) # Additional, we need to suggest the most recent version for each # branch, because we may want a build2 (or higher) of it. for branchVersions in recentBranches.values(): addVersionSuggestion(str(max(branchVersions))) # Finally, attach the suggestions to their fields. self.branch.suggestions = json.dumps(list(recentBranches.keys())) self.version.suggestions = json.dumps(list(suggestedVersions)) self.buildNumber.suggestions = json.dumps(buildNumbers)
class CreateRepositoryForm(Form): title = TextField("Title", validators = [Required()]) slug = TextField("Slug", validators = [ Optional(), Regexp("[0-9a-zA-Z\-_]", message = "The slug contains invalid characters. Only use alphanumeric characters, dashes and underscores.")]) clone_from = TextField("Clone from URL", validators = [Optional()])
class TagForm(Form): name = TextField('Name', [ Required(), Length(min=2, max=32), Regexp('^[a-z]+$', message='Tags must be [a-z].') ])
class ReleaseForm(Form): version = StringField('Version:', validators=[ Regexp(ANY_VERSION_REGEX, message='Invalid version format.') ]) buildNumber = IntegerField( 'Build Number:', validators=[DataRequired('Build number is required.')]) branch = StringField('Branch:', validators=[DataRequired('Branch is required')]) mozillaRevision = StringField('Mozilla Revision:') mozillaRelbranch = StringField('Mozilla Relbranch:', filters=[noneFilter]) comment = TextAreaField('Extra information to release-drivers:') description = TextAreaField('Description:') isSecurityDriven = BooleanField('Is a security driven release?', default=False) mh_changeset = StringField('Mozharness Revision:') release_eta_date = DateField('Release ETA date:', format='%Y-%m-%d', validators=[validators.optional()]) release_eta_time = StringField('Release ETA time:') VALID_VERSION_PATTERN = re.compile( r"""^(\d+)\.( # Major version number (0)(a1|a2|b(\d+)|esr)? # 2-digit-versions (like 46.0, 46.0b1, 46.0esr) |( # Here begins the 3-digit-versions. ([1-9]\d*)\.(\d+)|(\d+)\.([1-9]\d*) # 46.0.0 is not correct )(esr)? # Neither is 46.2.0b1 )(build(\d+))?$""", re.VERBOSE) # See more examples of (in)valid versions in the tests def __init__(self, suggest=True, *args, **kwargs): Form.__init__(self, *args, **kwargs) if suggest: self.addSuggestions() def validate(self, *args, **kwargs): valid = Form.validate(self, *args, **kwargs) # If a relbranch has been passed revision is ignored. if self.mozillaRelbranch.data: self.mozillaRevision.data = self.mozillaRelbranch.data # However, if a relbranch hasn't been passed, revision is required. else: if not self.mozillaRevision.data: valid = False self.errors['mozillaRevision'] = [ 'Mozilla revision is required' ] if self.VALID_VERSION_PATTERN.match(self.version.data) is None: valid = False self.errors['version'] = ['Version must match either X.0 or X.Y.Z'] return valid def addSuggestions(self): table = getReleaseTable(self.product.data) recentReleases = table.getRecent() # Before we make any suggestions we need to do some preprocessing of # the data to get it into useful structures. Specifically, we need a # set containing all of the recent versions, and a dict that associates # them with the branch they were built on. recentVersions = set() recentBranches = defaultdict(list) for release in recentReleases: recentVersions.add(release.version) recentBranches[release.branch].append(MozVersion(release.version)) # Now that we have the data in the format we want it in we can start # making suggestions. suggestedVersions = set() buildNumbers = {} # This wrapper method is used to centralize the build number suggestion # logic in one place, because there's more than one spot below that # adds a version suggestion. def addVersionSuggestion(version): suggestedVersions.add(version) # We want the UI to be able to automatically set build number # to the next available one for whatever version is entered. # To make this work we need to tell it what the next available # one is for all existing versions. We don't need to add versions # that are on build1, because it uses that as the default. maxBuildNumber = table.getMaxBuildNumber(version) if maxBuildNumber: buildNumbers[version] = maxBuildNumber + 1 else: buildNumbers[version] = 1 # Every version we see will have its potential next versions # suggested, except if we already have that version. # Note that we don't look through the entire table for every # version (because that could be expensive) but any versions # which are suggested and have already happened should be in # 'recentVersions', so it's unlikely we'll be suggesting # something that has already happened. for version in recentVersions: for v in getPossibleNextVersions(version): if v not in recentVersions: addVersionSuggestion(v) # Additional, we need to suggest the most recent version for each # branch, because we may want a build2 (or higher) of it. for branchVersions in recentBranches.values(): addVersionSuggestion(str(max(branchVersions))) # Finally, attach the suggestions to their fields. self.branch.suggestions = json.dumps(list(recentBranches.keys())) self.version.suggestions = json.dumps(list(suggestedVersions)) self.buildNumber.suggestions = json.dumps(buildNumbers) def updateFromRow(self, row): self.version.data = row.version self.buildNumber.data = row.buildNumber self.branch.data = row.branch # Revision is a disabled field if relbranch is present, so we shouldn't # put any data in it. if not row.mozillaRelbranch: self.mozillaRevision.data = row.mozillaRevision self.l10nChangesets.data = row.l10nChangesets self.mozillaRelbranch.data = row.mozillaRelbranch self.mh_changeset.data = row.mh_changeset if row.release_eta: release_eta = parse_iso8601_to_date_time(row.release_eta) self.release_eta_date.data = release_eta.date() # Conversion needed because release_eta_time is a StringField self.release_eta_time.data = release_eta.strftime('%H:%M %Z') @property def release_eta(self): if self.release_eta_date.data and self.release_eta_time.data: dt = self.release_eta_date.data tm = datetime.strptime(self.release_eta_time.data, '%H:%M %Z').time() return datetime.combine(dt, tm) else: return None
class CPUMemForm(Form): cpu = TextField(u'CPU', validators=[Regexp('^[0-9]+$', message=u'CPU核数必须为数字')]) mem = TextField(u'MEM', validators=[Regexp('^[0-9]+$', message=u'内存大小必须为数字')])
class LoginForm(Form): username = StringField('Username', validators=[ DataRequired(), Regexp('^[A-Za-z0-9\-_]+$', message='Only alphabets, numbers, hyphen, and underscore are allowed.') ]) password = PasswordField('Password', validators=[DataRequired()])
class AvaterForm(Form): avater = FileField(u'头像', validators=[Required(), Regexp(re_avater)])
class CategoryForm(Form): name = StringField('Name', validators=[DataRequired()]) slug = SlugField('name', label='Slug', validators=[ Regexp('^[0-9a-z\-]+$', message='Only lowercase alphabets, numbers, and hyphen are allowed.'), Unique(lambda: db.session, Category, Category.slug) ])
def __call__(self, form, field): if current_app.security.datastore.find_user(email=field.data): raise ValidationError(self.message) validators = { 'email': [ Required(), Email(), UniqueUser(message='Email address is associated with ' 'an existing account') ], 'password': [ Required(), Length(min=6, max=50), EqualTo('confirm', message='Passwords must match'), Regexp(r'[A-Za-z0-9@#$%^&+=]', message='Password contains invalid characters') ] } class RegisterForm(Form): email = TextField('Email', validators['email']) password = PasswordField( 'Password', validators['password'], ) confirm = PasswordField('Confirm Password')