【问题标题】:How to use current_user in a flask-wtforms Validator如何在烧瓶 wtforms 验证器中使用 current_user
【发布时间】:2023-04-04 01:55:03
【问题描述】:

有没有办法在自定义字段验证器中使用 current_user。这几乎就像是在系统设置时没有用户而不是在会话调用期间实例化验证器。

谢谢!

【问题讨论】:

    标签: python flask-wtforms flask-login


    【解决方案1】:

    您是否尝试过执行以下操作?我不知道它是否有效,但它允许您在运行时定义一个静态类并将 current_user 作为参数传递,该类从全局范围继承并且不会发生变异。

    def form_generator(current_user):
        class web_form:
            user_email = StringFiled('Email', validators=[Email()])
            def validate_user_email(self, field)
                if Model.query.filter(field.data == current_user.email).first()
                    return
                else:
                    return ValidationError("Email is not current user's")
        return web_form()
    

    在你的烧瓶路线然后尝试:

    form = form_generator(current_user)
    

    抱歉,这是未经测试的,我刚刚看到并发布了回复。但是,如果您尝试它,请告诉我它是否成功,或者更有趣的是为什么它失败了!!

    【讨论】:

      【解决方案2】:

      我还没有找到在运行时设置验证器的方法,但是有一种方法可以为表单类上的字段定义验证函数,并且该函数可以基于在构造时传递给表单的数据。这是一个例子

      class MyForm(flask_wtf.FlaskForm):
      
          user_id_field = wtforms.StringField("User ID")
      
          def __init__(self, valid_user_id, **kwargs):
      
              super().__init__(**kwargs)
              self.valid_user_id = valid_user_id
      
          def validate_user_id_field(self, field):
              """
              Function name must be 'validate_' + name of field you want to validate
              """
      
              if field.data != self.valid_user_id
      
                  raise wtforms.validators.ValidationError("Wrong user id!")
      
      
      # In endpoint definition:
      my_form = MyForm(formdata=flask.request.form, valid_user_id=flask_login.current_user.id)
      my_form.validate()
      

      编辑

      哈,事实证明在运行时设置验证器非常简单,只是文档没有在任何地方提到它。

      如果你有一个带有some_field字段的表单,你可以简单地在表单的构造函数中设置self.some_field.validators = [...],例如

      class MyForm(flask_wtf.FlaskForm):
      
          some_field = wtforms.HiddenField()
      
          def __init__(self, some_data, **kwargs):
      
              super().__init__(**kwargs)
      
              self.some_field.validators = [MyValidator(some_data)]
      
      # In endpoint
      form = MyForm(formdata=flask.request.form, some_data=some_data)
      

      或者您可以直接在端点处理程序中设置验证器:

      form = MyForm(formdata=flask.request.form)
      form.some_field.validators = [MyValidator(some_data)]
      

      【讨论】:

        【解决方案3】:

        虽然可以在运行时添加验证器,但这不是一个好的解决方案。必须在表单初始化后添加验证器!

        在我看来,更好的解决方案是简单地使用本地导入:

        class ValidateIfUserMayDoThis:
            def __init__(self, message):
                self.message
        
            def __call__(self, form, field):
                from flask_login import current_user   # DO THE IMPORT HERE!!!!
                if current_user.username in ['Donald']:
                    raise ValidationError(self.message)
        

        【讨论】:

          猜你喜欢
          • 2016-05-03
          • 1970-01-01
          • 2018-04-27
          • 1970-01-01
          • 2013-03-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多