python - Flask 管理员在更改用户模型时覆盖密码

标签 python flask flask-admin

我目前正在研究一个 flask 项目并第一次尝试使用 flask-admin。到目前为止一切正常,但有一件事真正困扰我: 每当我编辑我的用户模型时,用户密码都会被覆盖。我遵循 this question 的第二个答案中给出的建议以防止 flask-admin 重新散列我的密码。不幸的是,清空的密码字段仍会写入数据库。

我试图从 User-Model 获取当前密码,该模型作为 on_model_change 方法的参数给出,但不知何故密码似乎已经被覆盖那一点(或者这不是我在这里看到的实际数据库模型 - 我在这里有点困惑)。

这是我的代码:

用户模型

class User(UserMixin, SurrogatePK, Model):
    """A user of the app."""

    __tablename__ = 'users'
    username = Column(db.String(80), unique=True, nullable=False)
    email = Column(db.String(80), unique=True, nullable=False)
    #: The hashed password
    password = Column(db.String(128), nullable=True)
    created_at = Column(db.DateTime, nullable=False,
                        default=datetime.datetime.utcnow)
    first_name = Column(db.String(30), nullable=True)
    last_name = Column(db.String(30), nullable=True)
    active = Column(db.Boolean(), default=False)
    is_admin = Column(db.Boolean(), default=False)

    def __init__(self, username="", email="", password=None, **kwargs):
        """Create instance."""
        db.Model.__init__(self, username=username, email=email, **kwargs)
        if password:
            self.set_password(password)
        else:
            self.password = None

    def __str__(self):
        """String representation of the user. Shows the users email address."""
        return self.email

    def set_password(self, password):
        """Set password"""
        self.password = bcrypt.generate_password_hash(password)

    def check_password(self, value):
        """Check password."""
        return bcrypt.check_password_hash(self.password, value)

    def get_id(self):
        """Return the email address to satisfy Flask-Login's requirements"""
        return self.id

    @property
    def full_name(self):
        """Full user name."""
        return "{0} {1}".format(self.first_name, self.last_name)

    @property
    def is_active(self):
        """Active or non active user (required by flask-login)"""
        return self.active

    @property
    def is_authenticated(self):
        """Return True if the user is authenticated."""
         if isinstance(self, AnonymousUserMixin):
            return False
        else:
            return True

    @property
    def is_anonymous(self):
        """False, as anonymous users aren't supported."""
        return False

Flask-Admin 用户 View

class UserView(MyModelView):
    """Flask user model view."""
    create_modal = True
    edit_modal = True

    def on_model_change(self, form, User, is_created):
        if form.password.data is not None:
            User.set_password(form.password.data)
        else:
           del form.password

    def on_form_prefill(self, form, id):
        form.password.data = ''                                              

非常感谢任何帮助。 提前致谢,

梦境

最佳答案

覆盖 get_edit_form 方法并从编辑表单中完全删除密码字段可能更容易。

class UserView(MyModelView):
    def get_edit_form(self):
        form_class = super(UserView, self).get_edit_form()
        del form_class.password
        return form_class

另一种替代方法是从表单中完全删除模型密码字段,并使用一个虚拟密码字段,该字段随后可用于填充模型密码。通过删除真实的密码字段,Flask-Admin 将不会踩到我们的密码数据。示例:

class UserView(MyModelView):
    form_excluded_columns = ('password')
    #  Form will now use all the other fields in the model

    #  Add our own password form field - call it password2
    form_extra_fields = {
        'password2': PasswordField('Password')
    }

    # set the form fields to use
    form_columns = (
        'username',
        'email',
        'first_name',
        'last_name',
        'password2',
        'created_at',
        'active',
        'is_admin',
    )

    def on_model_change(self, form, User, is_created):
        if form.password2.data is not None:
            User.set_password(form.password2.data)

关于python - Flask 管理员在更改用户模型时覆盖密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39185230/

相关文章:

python - 使用 GraphQL 和 Graphene-Python 从数据库中选择仅请求的字段

python - Flask 错误处理 : "Response object is not iterable"

python - 如何协调运行 Flask-Login、Flask-BrowserID 和 Flask-SQLAlchemy?

python - Flask-Admin 默认过滤器

python - 使用 Flask-Admin 根据用户权限预过滤可读数据

python - Flask-admin 批处理操作,通过弹出模式窗口进行参数

Python - Selenium 下一页

python - 如何在 python 3 中解析 excel 文档中的文本?

python - 如何在 Django 中将 select_related 与 GenericForeignKey 一起使用?

python - 分割大型列表的最有效方法是什么?