I have two def validate(self)
functions within the RegistrationForm(FlaskForm)
. First function validates the user input if the car range is over 400km. The other function validates if the user lives far or close to work by calculating the distance between the user’s address and work address by means of geopy module. I’ve been told that def validate_field(self, field):
function takes only one attribute which must be the same as the field name. In that function I have an extra variable total_travel_km
that stores distance between work and user’s home. If user is validated than I need to store total_travel_km
variable in DB.
Now the server brings me this message: ‘RegistrationForm’ object has no attribute ‘total_travel_km’
How can I call that total_travel_km
variable correctly and write it inside DB
Here is the cut out from my code:
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
Advertisement
Answer
Set a form instance variable in the validation method:
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
Also, you might not want to hard code the car range limit, you can pass a value when you instance the form:
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')
and use as follows:
@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()