在WTForms中将对象传递给自定义验证器

Covrebo

编辑(试图澄清问题):
我为我的烧瓶应用程序创建的自定义验证器,用于检查重复的用户名和电子邮件,不适用于管理员用户修改其他用户帐户。当管理员用户编辑另一个用户的用户名或电子邮件时,验证器会指出它是重复的,因为它试图比较当前(管理员)用户的用户名和电子邮件,而不是正在编辑的用户的用户名和电子邮件。如何编写自定义验证器,以使用传递给下面的视图函数中的表单的用户对象,以比较正在编辑的用户的用户名和电子邮件,而不是已登录的用户?

原始帖子:
我正在开发Flask应用程序,该应用程序具有管理员权限的用户可以修改用户帐户信息。当前,我正在使用Flask-WTF和WTForms在用户个人资料页面上创建一个表单,帐户所有者或具有管理员特权的用户(通过用户模型中的角色分配)可以编辑用户信息。在视图功能中,我将用户信息传递给表单,以使用用户信息预填充表单字段。当我为帐户所有者制作个人资料编辑表单时,在提交表单时,我有一个自定义验证器,可将提交的数据与当前登录用户的数据进行比较,以检测是否有任何字段被编辑,然后检查是否有某些字段这些字段(例如用户名,电子邮件等)已经在数据库中,以避免重复。对于管理员用户可以编辑其他用户的表单,该验证器将继续防止将新值写入数据库,因为验证器会将登录的用户信息与数据库进行比较,而不是将属于正在编辑的帐户的用户信息与数据库进行比较。我想知道如何在提交表单时将用于填充表单字段的用户对象传递给表单验证?Flask应用程序正在使用蓝图结构。我对此很陌生,所以我希望这个问题有意义。这是一些我认为有帮助的代码。我想知道如何在提交表单时将用于填充表单字段的用户对象传递给表单验证?Flask应用程序正在使用蓝图结构。我对此很陌生,所以我希望这个问题有意义。这是一些我认为有帮助的代码。我想知道如何在提交表单时将用于填充表单字段的用户对象传递给表单验证?Flask应用程序正在使用蓝图结构。我对此很陌生,所以我希望这个问题有意义。这是一些我认为有帮助的代码。

这是视图功能:

# Edit account view function for admin users
@users.route('/edit-account/<int:user_id>', methods=['GET', 'POST'])
@login_required
def edit_account(user_id):
    # Get the info for the user being edited
    user = User.query.get_or_404(user_id)
    # Check to be sure user has admin privileges
    if current_user.role != 'admin' and current_user.role != 'agent':
        abort(403)
    form = AccountEditForm()
    if form.validate_on_submit():
        # Update the profile picture, if a file is submitted
        if form.profile_pic.data:
            picture_file = save_picture(form.profile_pic.data)
            user.profile_pic = picture_file
        # Update the database entries for the user
        user.username = form.username.data
        user.first_name = form.first_name.data
        user.last_name = form.last_name.data
        user.email = form.email.data
        user.role = form.role.data
        db.session.commit()
        flash(f'The account for {user.first_name} {user.last_name} has been updated.', 'success')
        return redirect(url_for('users.users_admin'))
    # Pre-populate the form with existing data
    elif request.method == 'GET':
        form.username.data = user.username
        form.first_name.data = user.first_name
        form.last_name.data = user.last_name
        form.email.data = user.email
        form.role.data = user.role
    image_file = url_for('static', filename=f'profile_pics/{user.profile_pic}')
    return render_template('account.html', title='account',
                           image_file=image_file, form=form, user=user)

当管理员用户试图编辑另一个用户的帐户时,以下表单类不适用于验证器:

class AccountEditForm(FlaskForm):
    username = StringField('Username',
                           validators=[DataRequired(), Length(min=2, max=20)])
    first_name = StringField('First Name',
                             validators=[DataRequired(), Length(min=2, max=32)])
    last_name = StringField('Last Name',
                            validators=[DataRequired(), Length(min=2, max=32)])
    email = StringField('Email',
                        validators=[DataRequired(), Email()])
    profile_pic = FileField('Update Profile Picture',
                            validators=[FileAllowed(['jpg', 'png'])])
    role = SelectField('Role', validators=[DataRequired()],
                       choices=[('admin', 'Admin'), ('agent', 'Agent'), ('faculty', 'Faculty'),
                                ('staff', 'Staff'), ('student', 'Student')])
    submit = SubmitField('Update')

    # Custom validation to check for duplicate usernames
    def validate_username(self, username):
        # Check to see if the form data is different than the current db entry
        if username.data != username:
            # Query db for existing username matching the one submitted on the form
            user = User.query.filter_by(username=username.data).first()
            if user:
                raise ValidationError('Username is taken, please choose another.')

    # Custom validation to check for duplicate email
    def validate_email(self, email):
        # Check to see if the form data is different than the current db entry
        if email.data != user.email:
            # Query db for existing email matching the one submitted on the form
            user = User.query.filter_by(email=email.data).first()
            if user:
                raise ValidationError('Email is already used, please choose another or login.')

这是当用户从其他表单类编辑自己的帐户时可以使用的自定义验证器:

# Custom validation to check for duplicate usernames
def validate_username(self, username):
    # Check to see if the form data is different than the current db entry
    if username.data != current_user.username:
        # Query db for existing username matching the one submitted on the form
        user = User.query.filter_by(username=username.data).first()
        if user:
            raise ValidationError('Username is taken, please choose another.')

# Custom validation to check for duplicate email
def validate_email(self, email):
    # Check to see if the form data is different than the current db entry
    if email.data != current_user.email:
        # Query db for existing email matching the one submitted on the form
        user = User.query.filter_by(email=email.data).first()
        if user:
            raise ValidationError('Email is already used, please choose another or login.')
李丽

这是将对象传递给自定义验证器的示例,该方案与您的方案完全相同:

class EditProfileAdminForm(EditProfileForm):
    email = StringField('Email', validators=[DataRequired(), Length(1, 254), Email()])
    role = SelectField('Role', coerce=int)
    active = BooleanField('Active')
    confirmed = BooleanField('Confirmed')
    submit = SubmitField()

    def __init__(self, user, *args, **kwargs):  # accept the object
        super(EditProfileAdminForm, self).__init__(*args, **kwargs)
        self.role.choices = [(role.id, role.name)
                             for role in Role.query.order_by(Role.name).all()]
        self.user = user  # set the object as class attr

    def validate_username(self, field):
        # use self.user.username to get the user's username
        if field.data != self.user.username and User.query.filter_by(username=field.data).first():
            raise ValidationError('The username is already in use.')

    def validate_email(self, field):
        if field.data != self.user.email and User.query.filter_by(email=field.data.lower()).first():
            raise ValidationError('The email is already in use.')


# view function
@admin_bp.route('/profile/<int:user_id>', methods=['GET', 'POST'])
@login_required
@admin_required
def edit_profile_admin(user_id):
    user = User.query.get_or_404(user_id)
    form = EditProfileAdminForm(user=user)  # pass the object
    # ...

示例代码来自照片共享应用程序

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何将对象属性作为参数传递给Struts自定义验证器

来自分类Dev

通过属性将对象传递给自定义组件

来自分类Dev

将对象传递给自定义指令而不创建观察者?

来自分类Dev

无法将对象传递给我的自定义复合控件

来自分类Dev

将自定义对象传递给WTForm

来自分类Dev

将自定义对象传递给TestNG结果监听器

来自分类Dev

将自定义对象传递给TestNG结果侦听器

来自分类Dev

将对象传递给装饰器

来自分类Dev

在jQuery中将对象传递给回调函数

来自分类Dev

在AngularJS中将对象传递给$ http POST

来自分类Dev

在jQuery中将对象传递给回调函数

来自分类Dev

Polymer / PolymerTS:将对象传递到自定义元素

来自分类Dev

如何将实体对象从自定义验证注释传递给控制器

来自分类Dev

AngularJS将对象传递给控制器

来自分类Dev

AngularJS将对象传递给控制器

来自分类Dev

将自定义C ++对象传递给Qml错误(无属性)

来自分类Dev

如何通过主干将自定义对象传递给REST?

来自分类Dev

将自定义对象传递给Progress Changed方法。C#

来自分类Dev

想要将ng-repeat对象传递给自定义过滤器功能

来自分类Dev

如何通过PendingIntent将自定义Serializable对象传递给BroadcastReceiver

来自分类Dev

通过ngFor将接口对象传递给自定义组件

来自分类Dev

将自定义对象传递给另一个片段

来自分类Dev

将自定义对象传递给Progress Changed方法。C#

来自分类Dev

将自定义类对象传递给Java中的泛型类型

来自分类Dev

Xpages:将JSON对象传递给自定义控件以构建菜单

来自分类Dev

如何将自定义对象传递给应用引擎端点

来自分类Dev

Python将对象传递给对象

来自分类Dev

将对象传递给组件

来自分类Dev

将对象传递给SASlideMenuViewController子类

Related 相关文章

  1. 1

    如何将对象属性作为参数传递给Struts自定义验证器

  2. 2

    通过属性将对象传递给自定义组件

  3. 3

    将对象传递给自定义指令而不创建观察者?

  4. 4

    无法将对象传递给我的自定义复合控件

  5. 5

    将自定义对象传递给WTForm

  6. 6

    将自定义对象传递给TestNG结果监听器

  7. 7

    将自定义对象传递给TestNG结果侦听器

  8. 8

    将对象传递给装饰器

  9. 9

    在jQuery中将对象传递给回调函数

  10. 10

    在AngularJS中将对象传递给$ http POST

  11. 11

    在jQuery中将对象传递给回调函数

  12. 12

    Polymer / PolymerTS:将对象传递到自定义元素

  13. 13

    如何将实体对象从自定义验证注释传递给控制器

  14. 14

    AngularJS将对象传递给控制器

  15. 15

    AngularJS将对象传递给控制器

  16. 16

    将自定义C ++对象传递给Qml错误(无属性)

  17. 17

    如何通过主干将自定义对象传递给REST?

  18. 18

    将自定义对象传递给Progress Changed方法。C#

  19. 19

    想要将ng-repeat对象传递给自定义过滤器功能

  20. 20

    如何通过PendingIntent将自定义Serializable对象传递给BroadcastReceiver

  21. 21

    通过ngFor将接口对象传递给自定义组件

  22. 22

    将自定义对象传递给另一个片段

  23. 23

    将自定义对象传递给Progress Changed方法。C#

  24. 24

    将自定义类对象传递给Java中的泛型类型

  25. 25

    Xpages:将JSON对象传递给自定义控件以构建菜单

  26. 26

    如何将自定义对象传递给应用引擎端点

  27. 27

    Python将对象传递给对象

  28. 28

    将对象传递给组件

  29. 29

    将对象传递给SASlideMenuViewController子类

热门标签

归档