如何在 FlaskForm class 内的 validate() 函数外部调用变量

How to call a variable outside a validate() function which is inside the FlaskForm class

我在 RegistrationForm(FlaskForm) 中有两个 def validate(self) 函数。如果汽车续航里程超过 400 公里,第一个函数会验证用户输入。另一个功能通过使用 geopy 模块计算用户地址和工作地址之间的距离来验证用户是住得远还是离工作近。有人告诉我 def validate_field(self, field): 函数只接受一个必须与字段名称相同的属性。在那个函数中,我有一个额外的变量 total_travel_km 来存储工作地点和用户家之间的距离。如果用户通过验证,我需要在数据库中存储 total_travel_km 变量。

现在服务器给我这个消息:'RegistrationForm' object has no attribute 'total_travel_km'

如何正确调用 total_travel_km 变量并将其写入 DB

这是从我的代码中截取的:

class RegistrationForm(FlaskForm):
    car_range = IntegerField('Car Range, km')
    home_address = StringField('Home Address')
    submit = SubmitField('Register User/Car')
    
    def validate_car_range(self, car_range):
        if car_range.data > 400:
            raise ValidationError('Your car range does not meet our requirements')

    def validate_home_address(self, home_address):
        user_loc = locator.geocode(home_address.data)
        user_coords = (user_loc.latitude, user_loc.longitude)
        one_way = geopy.distance.geodesic(tco_coords, user_coords).km
        total_travel_km = one_way*4
        if total_travel_km < self.car_range.data:
            raise ValidationError('You live too close to work')
        return total_travel_km

@app.route("/register", methods=['POST', 'GET'])
def register():
    form = RegistrationForm()
    if form.validate_on_submit():
        user = User(car_range=form.car_range.data, home_address=form.home_address.data,
                    car_travel_km=form.total_travel_km)
        db.session.add(user)
        db.session.commit()

EDIT: I figured out. I had to pass form. instead of self. in validation method. Below is the correct code:

def validate_home_address(form, home_address):
            user_loc = locator.geocode(home_address.data)
            user_coords = (user_loc.latitude, user_loc.longitude)
            one_way = geopy.distance.geodesic(tco_coords, user_coords).km
            form.total_travel_km = one_way*4
            if form.total_travel_km < self.car_range.data:
                raise ValidationError('You live too close to work')
            return form.total_travel_km

在验证方法中设置一个表单实例变量:

class RegistrationForm(FlaskForm):

    def __init__(self, *args, **kwargs):
        super(RegistrationForm, self).__init__(*args, **kwargs)
        self.total_travel_km = None

    def validate_home_address(self, home_address):
        user_loc = locator.geocode(home_address.data)
        user_coords = (user_loc.latitude, user_loc.longitude)
        one_way = geopy.distance.geodesic(tco_coords, user_coords).km
        total_travel_km = one_way * 4
        if total_travel_km < self.car_range.data:
            raise ValidationError('You live too close to work')
        # all good save the total travel in the form
        self.total_travel_km = total_travel_km

此外,您可能不想对汽车续航里程限制进行硬编码,您可以在实例化表单时传递一个值:

class RegistrationForm(FlaskForm):

    def __init__(self, *args, **kwargs):
        super(RegistrationForm, self).__init__(*args, **kwargs)
        self.total_travel_km = None
        self.required_car_range = kwargs.get('required_car_range', 400)

    def validate_car_range(self, car_range):
        if car_range.data > self.required_car_range:
            raise ValidationError('Your car range does not meet our requirements')

并按如下方式使用:

@app.route("/register", methods=['POST', 'GET'])
def register():
    form = RegistrationForm(required_car_range=600)
    if form.validate_on_submit():
        user = User(car_range=form.car_range.data, home_address=form.home_address.data,
                    car_travel_km=form.total_travel_km)
        db.session.add(user)
        db.session.commit()