How can I clear values from WTF form upon submission? [duplicate] - python

I want to reset the form after it validates. Currently the form will still show the previous data after it is submitted and valid. Basically, I want the form to go back to the original state with all fields clean. What is the correct to do this?
#mod.route('/', methods=['GET', 'POST'])
def home():
form = NewRegistration()
if form.validate_on_submit():
#save in db
flash(gettext(u'Thanks for the registration.'))
return render_template("users/registration.html", form=form)

The issue is that you're always rendering the form with whatever data was passed in, even if that data validated and was handled. In addition, the browser stores the state of the last request, so if you refresh the page at this point the browser will re-submit the form.
After handling a successful form request, redirect to the page to get a fresh state.
#app.route('/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
# do stuff with valid form
# then redirect to "end" the form
return redirect(url_for('register'))
# initial get or form didn't validate
return render_template('register.html', form=form)

davidism answer is correct.
But once I had to reload a form with only a few fields that had to be resetted.
So, I did this, maybe it's not the cleanest way but it worked for me:
form = MyForm()
if form.validate_on_submit():
# save all my data...
myvar1 = form.field1.data
myvar2 = form.field2.data
# etc...
# at first GET and at every reload, this is what gets executed:
form.field1.data = "" # this is the field that must be empty at reload
form.field2.data = someobject # this is a field that must be filled with some value that I know
return render_template('mypage.html', form=form)

You can clear a form by passing formdata=None
#mod.route('/', methods=['GET', 'POST'])
def home():
form = NewRegistration()
if form.validate_on_submit():
#save in db
######### Recreate form with no data #######
form = NewRegistration(formdata=None)
flash(gettext(u'Thanks for the registration.'))
return render_template("users/registration.html", form=form)

you can also return new form object using render_template if form does not validates you can also pass message
#mod.route('/', methods=['GET', 'POST'])
def home():
form = NewRegistration()
if form.validate_on_submit():
#save in db
return render_template("user/registration.html", form = NewRegistration())
return render_template("users/registration.html", form=form)

Related

Optional keyword argument in render_template

Here is my code:
#app.route('/', methods=['GET', 'POST'])
def index():
form = CryptoForm()
if session.get('currency'):
currency = session.get('currency')
price1 = Get_info(currency)
price = price1.get_filtered_data()
if form.validate_on_submit():
flash('success', 'success')
currency = form.crypto.data
get_price = Get_info(currency)
session['currency'] = get_price.get_filtered_data()
return redirect(url_for('index'))
return render_template("index.html", form=form, price=price)
What I'm trying to do is to get the user to type a crypto acronym into the form and submit it. When the user submits it, it should display the price. But when the page loads for first time there is no price so the price=price in render_template is giving me error. How could I fix it so there is a price only if he submit the form?
If you want to do different things whether the form is submitted or not, check what the method is.
from flask import request
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
# The user submitted something.
else:
# The user fetched something.

AttributeError: 'FileField' object has no attribute 'save' - Flask - WTForms [duplicate]

How do I get the data from a WTForms form after submitting it? I want to get the email entered in the form.
class ApplicationForm(Form):
email = StringField()
#app.route('/', methods=['GET', 'POST'])
def index():
form = ApplicationForm()
if form.validate_on_submit():
return redirect('index')
return render_template('index.html', form=form)
<form enctype="multipart/form-data" method="post">
{{ form.csrf_token }}
{{ form.email }}
<input type=submit>
</form>
Each field has a data attribute containing the processed data.
the_email = form.email.data
Working with form data is described in the getting started doc.
The most probable place for you to do things with the Form.attrs is in the index function. I have added some conditional guards on the method param. You want to do different things if they are using GET or POST as well. There are other ways to do all of this but I didn't want to change too much at once. But you should think about it clearly this way. If I have no form data because I've just made the initial request, I'm going to be using GET. Once I render the form in the template, I'm going to be sending a POST (as you can see in the top of your template). So I need those two cases dealt with firstly.
Then, once the form is rendered and returned I will have data or no data. So dealing with the data is going to happen in the POST branch of the controller.
#app.route('/index', methods=['GET', 'POST'])
def index():
errors = ''
form = ApplicationForm(request.form)
if request.method == 'POST':
if form.is_submitted():
print "Form successfully submitted"
if form.validate_on_submit():
flash('Success!')
# Here I can assume that I have data and do things with it.
# I can access each of the form elements as a data attribute on the
# Form object.
flash(form.name.data, form.email.data)
# I could also pass them onto a new route in a call.
# You probably don't want to redirect to `index` here but to a
# new view and display the results of the form filling.
# If you want to save state, say in a DB, you would probably
# do that here before moving onto a new view.
return redirect('index')
else: # You only want to print the errors since fail on validate
print(form.errors)
return render_template('index.html',
title='Application Form',
form=form)
elif request.method == 'GET':
return render_template('index.html',
title='Application Form',
form=form)
To help, I'm adding a simple example from some of my working code. You should be able to follow it given your code and my walk through.
def create_brochure():
form = CreateBrochureForm()
if request.method == 'POST':
if not form.validate():
flash('There was a problem with your submission. Check the error message below.')
return render_template('create-brochure.html', form=form)
else:
flash('Succesfully created new brochure: {0}'.format(form.name.data))
new_brochure = Brochure(form.name.data,
form.sales_tax.data,
True,
datetime.datetime.now(),
datetime.datetime.now())
db.session.add(new_brochure)
db.session.commit()
return redirect('brochures')
elif request.method == 'GET':
return render_template('create-brochure.html', form=form)

How to give arguments to view with flask, redirect url_for

I have an application build with flask and I want to pass one input tag from my current html view ('/setpickup') to another view, in order to reuse the variable values of that input and print them again in the new view ('/payments.html'). But I dont know if it is possible, thanks you. Here is a brief of the code that is not working at this moment.
#app.route('/')
#app.route('/setpickup', methods=['GET', 'POST'])
#login_required
def setpickup():
form = RideForm()
device = Utils.getDevice()
if request.method == 'POST':
data_input_data = form.data_input.data
return redirect(url_for('payment', data_input_data=data_input_data))
#app.route('/payment')
#login_required
def payment(data_input_data):
device = Utils.getDevice()
return render_template("/"+device+"/payment.html",
device=device,
data_input_data=data_input_data)

Submitting edited Prepopulate Flask-WTForm data from database

I would like to pre-populate my form with data from my database to make necessary changes and modify my database with these changes.
However when i run the following code below, when the form.validate_on_submit() method is initialised, the form's data is the pre-populated data from the database and not the edited version. How do i access the edited value of the form data?
#auth.route('/edit_projects', methods=['GET', 'POST'])
#auth.route('/edit_projects/<project>', methods=['GET', 'POST'])
#login_required
def edit_projects(project=None):
form = ProjectForm()
project_db = Project.query.all()
edit_project_db = Project.query.filter_by(id=project).first()
if project != None:
form.name.data=edit_project_db.name
form.project_brief.data=edit_project_db.project_brief
form.project_description.data=edit_project_db.project_description
if form.validate_on_submit():
edit_project_db.name = form.name.data
edit_project_db.project_brief = form.project_brief.data
edit_project_db.project_description = form.project_description.data
db.session.commit()
flash('Product %s updated.' %(str(form.name.data)))
I think it could help to distinguish between 'GET' and 'POST', on 'GET' you prepopulate the fields, but on 'POST' you want to see if the user has actually edited the form content.
I would split the code like:
if request.method == 'GET':
# prepopulate
if project != None:
form.name.data=edit_project_db.name
form.project_brief.data=edit_project_db.project_brief
elif request.method == 'POST':
# check form validates
if form.validate_on_submit():
# keep the rest as it is
...
Hope this offers some help.

Redirect to other view after submitting form

I have a survey form. After submitting the form, I'd like to handle saving the data then redirect to a "success" view. I'm using the following code right now, but it just stays on the current url, while I'd like to go to /success. How can I do this?
#app.route('/surveytest', methods=['GET', 'POST'])
def surveytest():
if request.method == 'GET':
return render_template('test.html', title='Survey Test', year=datetime.now().year, message='This is the survey page.')
elif request.method == 'POST':
name = request.form['name']
address = request.form['address']
phone = request.form['phone']
email = request.form['email']
company = request.form['company']
return render_template('success.html', name=name, address=address, phone = phone, email = email, company = company)
You have the right goal: it's good to redirect after handling form data. Rather than returning render_template again, use redirect instead.
from flask import redirect, url_for, survey_id
#app.route('/success/<int:result_id>')
def success(result_id):
# replace this with a query from whatever database you're using
result = get_result_from_database(result_id)
# access the result in the tempalte, for example {{ result.name }}
return render_template('success.html', result=result)
#app.route('/survey', methods=["GET", "POST"])
def survey():
if request.method == 'POST':
# replace this with an insert into whatever database you're using
result = store_result_in_database(request.args)
return redirect(url_for('success', result_id=result.id))
# don't need to test request.method == 'GET'
return render_template('survey.html')
The redirect will be handled by the user's browser, and the new page at the new url will be loaded, rather than rendering a different template at the same url.
Though I am not specifically answering your current question I found myself with a similar problem with getting the page to redirect after the submission button had been clicked. So I hope this solution could potentially work for others that find themselevs in a similar predicament.
This example uses Flask forms for handling forms and submissions.
from flast_wtf import FlaskForm
#app.route("/", methods=["GET", "POST"])
def home():
stock_form = StockForm()
tick = stock_form.text_field.data
if tick != None:
return redirect(f'/{tick}', code=302)
return render_template("home.html", template_form=stock_form, ticker=tick)
The if statement checks that the submission after being clicked has a value, then redirects to your chosen link. This code is a copy and paste from a badly programmed stock price lookup.

Categories