简体   繁体   English

尝试将 3 个 wtforms 字段与自定义函数进行比较并遇到递归问题

[英]Trying to compare 3 wtforms fields with custom functions and geting recursion problem

I have 3 fields that I want to compare salary "from" field and "to" field and also there is fixed salary field.我有 3 个字段,我想比较“来自”字段和“到”字段的薪水,并且还有固定薪水字段。 I have no idea how to do it, since there is no documentation how to do it, so i created custom function that look to each other and trying to se if they have a value.我不知道该怎么做,因为没有文档可以做到这一点,所以我创建了相互查看的自定义函数并尝试确定它们是否有价值。

def validate_salarylow(self, salarylow):
        if self.validate_salary_fixed(self.salary_fixed) != "":
               salarylow.data = int(0)   
        else:
            try:
                salarylow.data = int(salarylow.data)
            except:
                raise ValidationError("value is not a number")
        return salarylow.data

    def validate_salary_high(self, salary_high):      
        if self.validate_salary_fixed(self.salary_fixed) != "":
               salary_high.data = int(0)      
        else:
            try:
                salary_high.data = int(salary_high.data)
            except:
                raise ValidationError("value is not a number")
        return salary_high.data       

    def validate_salary_fixed(self, salary_fixed):
        if self.validate_salary_high(self.salary_high) != "":
               salary_fixed.data = int(0)
        try:
            salary_fixed.data = int(salary_fixed.data)   
        except:
            raise ValidationError("value is not a number")
        return salary_fixed.data 

if I don't set if self.validate_salary_high(self.salary_high) != "": everything works fine.如果我不设置if self.validate_salary_high(self.salary_high) != "":一切正常。 but when i set it I'm getting "RecursionError: maximum recursion depth exceeded" error.validate_salary_fixed function looks to validate_salary_high function and vice versa.但是当我设置它时,我得到“RecursionError:超出最大递归深度”error.validate_salary_fixed 函数看起来是 validate_salary_high 函数,反之亦然。 I'm new in Python and flask and I'm sure there is easy solution, but I cant find it so I would appreciate if anyone could help.我是 Python 和烧瓶的新手,我确信有简单的解决方案,但我找不到它,所以如果有人能提供帮助,我将不胜感激。

Let's take a look at your code:让我们看一下您的代码:

  1. Your function validate_salary_high calls validate_salary_fixed .您的函数validate_salary_high调用validate_salary_fixed
  2. But when you go to your function validate_salary_fixed it calls validate_salary_high .但是,当您使用validate_salary_fixed函数时,它会调用validate_salary_high
  3. So you go back to your function validate_salary_high which calls validate_salary_fixed .所以你回到你的函数validate_salary_high调用validate_salary_fixed
  4. Now in your function validate_salary_fixed , you call validate_salary_high .现在在您的函数validate_salary_fixed中,您调用validate_salary_high

Your functions repeatedly call each other over and over again, forever, until your computer eventually throws an error - and this is exactly what is happening to you.你的函数一次又一次地相互调用,直到你的计算机最终抛出一个错误——这正是发生在你身上的事情。

The way to get around this is to remove one of your recursive calls.解决此问题的方法是删除您的一个递归调用。 More specifically you should either更具体地说,您应该

  1. remove your call to validate_salary_fixed in the function validate_salary_high在函数validate_salary_high中删除您对validate_salary_fixed的调用
  2. or remove your call to validate_salary_high in the function validate_salary_fixed或在函数validate_salary_fixed中删除您对validate_salary_high的调用

You should chose which function call to remove depending on the goal of your code (which I don't fully understand.) Good luck!您应该根据代码的目标(我不完全理解)选择要删除的函数调用。祝你好运!

My suggestion is to suppress the error message of the integer field by overwriting it.我的建议是通过覆盖它来抑制整数字段的错误消息。 Thus, the types of the inputs do not have to be converted.因此,不必转换输入的类型。
For validation I use two custom validators, one of which checks whether a range or a fixed value has been entered and the second checks the range for its limits.对于验证,我使用了两个自定义验证器,其中一个检查是否输入了范围或固定值,第二个检查范围的限制。 In addition, pre-built validators are used to prohibit negative values.此外,预先构建的验证器用于禁止负值。
I'm not sure if you really need the field for the fixed salary, because it is possible to define a fixed value by narrowing the range.我不确定您是否真的需要固定薪水的字段,因为可以通过缩小范围来定义固定值。

from flask_wtf import FlaskForm
from wtforms import IntegerField
from wtforms.validators import (
    NumberRange,
    Optional,
    StopValidation,
    ValidationError
)

class OptionalIntegerField(IntegerField):
    def process_data(self, value):
        try:
            super().process_data(value)
        except ValueError:
            pass

    def process_formdata(self, valuelist):
        try:
            super().process_formdata(valuelist)
        except ValueError:
            pass

def validate_salary(form, field):
    range_fields = [form.salary_low, form.salary_high]
    if all(f.data is None for f in [form.salary_low, form.salary_high, form.salary_fixed]) or \
        (form.salary_fixed.data is not None and any(f.data is not None for f in range_fields)) or \
        (form.salary_fixed.data is None and any(f.data is None for f in range_fields)):
        raise StopValidation('Either state a range from low to high or a fixed salary.')

def validate_salary_range(form, field):
    if form.salary_low.data and form.salary_high.data and \
        form.salary_low.data > form.salary_high.data:
        raise ValidationError('The lower value should be less than or equal to the higher one.')

class SalaryForm(FlaskForm):
    salary_low = OptionalIntegerField(
        validators=[
            validate_salary,
            validate_salary_range,
            Optional(),
            NumberRange(min=0)
        ]
    )
    salary_high = OptionalIntegerField(
        validators=[
            validate_salary,
            validate_salary_range,
            Optional(),
            NumberRange(min=0)
        ]
    )
    salary_fixed = OptionalIntegerField(
        validators=[
            validate_salary,
            Optional(),
            NumberRange(min=0)
        ]
    )

app = Flask(__name__)
app.secret_key = 'your secret here'

@app.route('/', methods=['GET', 'POST'])
def index():
    form = SalaryForm(request.form)
    if form.validate_on_submit():
        print(form.salary_low.data, ' - ', form.salary_high.data, '||', form.salary_fixed.data)
    return render_template('index.html', **locals())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM