You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
## Imports for forms with Flask-WTF and Flask-Bootstrap
42
45
43
46
You will have a long list of imports at the top of your Flask app file:
@@ -68,7 +71,7 @@ Bootstrap(app)
68
71
69
72
Flask allows us to set a "secret key" value. You can grab a string from a site such as [RandomKeygen](https://randomkeygen.com/). This value is used to prevent malicious hijacking of your form from an outside submission.
70
73
71
-
Flask-WTF's `FlaskForm` will automatically create a secure session with CSRF (cross-site request forgery) protection if this key-value is set. Don't publish the actual key on GitHub!
74
+
Flask-WTF's `FlaskForm` will automatically create a secure session with CSRF (cross-site request forgery) protection if this key-value is set. **Don't publish the actual key on GitHub!**
72
75
73
76
You can read more about `app.config['SECRET_KEY']` in [this StackOverflow post](https://stackoverflow.com/questions/22463939/demystify-flask-app-secret-key).
74
77
@@ -86,7 +89,9 @@ class NameForm(FlaskForm):
86
89
submit = SubmitField('Submit')
87
90
```
88
91
89
-
Note that `StringField` and `SubmitField` were **imported** at the top of the file. If we needed other form fields in this form, we would need to import those. See a [list of all WTForms field types](WTForms-field-types.csv).
92
+
[Learn more about classes in Python here.](https://docs.python.org/3/tutorial/classes.html#a-first-look-at-classes)
93
+
94
+
Note that `StringField` and `SubmitField` were **imported** at the top of the file. If we needed other form fields in this form, we would need to import those also. See a [list of all WTForms field types](WTForms-field-types.csv).
90
95
91
96
Note that several field types (such as `RadioField` and `SelectField`) must have an option `choices=[]` specified, after the label text. Within the list, each choice is a pair in this format: `('string1', 'string2')`.
92
97
@@ -100,12 +105,15 @@ Now we will use the form in a Flask route:
100
105
@app.route('/', methods=['GET', 'POST'])
101
106
defindex():
102
107
names = get_names(ACTORS)
103
-
#you must tell the variable 'form' what you named the class, above
104
-
#'form' is the variable name used in this template: index.html
108
+
#ACTORS is a list of dictionaries for 100 movie actors, imported with -
109
+
#from data import ACTORS
105
110
form = NameForm()
111
+
# 'form' is the variable name used in this template: index.html
112
+
# NameForm() is the class, explained above
106
113
message =""
107
114
if form.validate_on_submit():
108
115
name = form.name.data
116
+
# get the text (data) out of the form control with the name "name"
So when you use `wtf.quick_form()`, the argument in the parentheses must be the *variable* that represents the form you created in the app.
173
+
So when you use `wtf.quick_form()`, the argument inside the parentheses must be the *variable* that represents the form you created in the app.
166
174
167
175
```python
168
176
form = NameForm()
@@ -175,7 +183,7 @@ We discussed the configuration of `NameForm` above.
175
183
Before reading further, try out [a working version of this app](https://weimergeeks.com/flask_form/). The complete code for the app is in this repo in the folder *actors_app*.
176
184
177
185
1. You type an actor's name into the form and submit it.
178
-
2. If the actor's name is in the data source, the app loads a detail page for that actor.
186
+
2. If the actor's name is in the data source (ACTORS), the app loads a detail page for that actor. (Photos of bears stand in for real photos of the actors.)
179
187
3. Otherwise, you stay on the same page, the form is cleared, and a message tells you that actor is not in the database.
180
188
181
189
```python
@@ -205,7 +213,7 @@ First we have the route, as usual, but with a new addition for handling form dat
205
213
@app.route('/', methods=['GET', 'POST'])
206
214
```
207
215
208
-
Every HTML form has two possible methods, `GET` and `POST`. `GET` simply requests a response from the server. `POST`, however, sends a request with data attached in the body of the request; this is the way most forms are submitted.
216
+
Every HTML form has two possible methods, `GET` and `POST`. `GET` simply requests a response from the server. `POST`, however, sends a request **with data attached** in the body of the request; this is the way most forms are submitted.
209
217
210
218
This route needs to use both methods because when we simply open the page, no form was submitted, and we're opening it with `GET`. When we submit the form, this same page is opened with `POST` if the actor's name (the form data) was not found.
211
219
@@ -259,8 +267,12 @@ This if-statement is specific to this app. It checks whether the `name` (that wa
259
267
return redirect( url_for('actor', id=id) )
260
268
```
261
269
270
+
Thus `redirect( url_for('actor', id=id) )` is calling a different route here in the same Flask app script. [See lines 46-55 here.](actors_app/actors.py)
271
+
262
272
As far as **using forms with Flask** is concerned, you don't need to worry about the actors and their ids, etc. What is important is that the route function can be used to *evaluate the data sent from the form.* We check to see whether it matched any of the actors in a list, and *a different response* will be sent based on match or no match.
263
273
274
+
You could do *any* of the things that are typically done with HTML forms — handle usernames and passwords, write new data to a database, create a quiz, etc.
275
+
264
276
The final line in the route function calls the template *index.html* and passes three variables to it:
Adding **Flask-Bootstrap** ensures that we can build mobile-friendly forms with a minimum amount of effort.
275
287
276
-
Note that it is possible to build a customized form layout using Bootstrap 3 styles in a Flask template, or to build a custom form with no Bootstrap styles. In either case, you cannot use `{{ wtf.quick_form(form) }}` but would instead write out all the form code in your Flask template as you would in a normal HTML file. To take advantage of WTForms, you would still create the form class with `FlaskForm` in the same way as shown above.
288
+
Note that it is possible to build a customized form layout using Bootstrap 4 styles in a Flask template, or to build a custom form with no Bootstrap styles. In either case, you cannot use `{{ wtf.quick_form(form) }}` but would instead write out all the form code in your Flask template as you would in a normal HTML file. To take advantage of WTForms, you would still create the form class with `FlaskForm` in the same way as shown above.
277
289
278
-
**IMPORTANT:** In early 2018, Bootstrap 4 replaced Bootstrap 3. The differences are significant; names and usage of styles have changed. For the time being, Flask-Bootstrap uses Bootstrap 3.3.7, so if you're writing Bootstrap styles into a Flask template, it is imperative that you use the [Bootstrap 3 documentation](https://getbootstrap.com/docs/3.3/css/).
290
+
**IMPORTANT:**Note that you are using Bootstrap 4 if you installed with `pip3 install Flask-Bootstrap4`. In early 2018, Bootstrap 4 replaced Bootstrap 3. The differences are significant; names and usage of styles have changed. Refer to the [Bootstrap 4 documentation](https://getbootstrap.com/docs/4.3/layout/grid/) for correct usage of Bootstrap styles.
279
291
280
292
## Resources
281
293
282
-
*[Sending form data](https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_and_retrieving_form_data)– how web browsers interact with servers; request/response
294
+
*[Sending form data](https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_and_retrieving_form_data)— how web browsers interact with servers; request/response
By viewing *base.html* in *templates/bootstrap,* you can find the Jinja2 directives that surround the HEAD, list of attached CSS files, footer area, etc. You can then use those directives in your own templates for finer control.
Note that Flask-Bootstrap uses Bootstrap 3.x, not Bootstrap 4.
308
+
By viewing *base.html* in *templates/bootstrap,* you can find the Jinja2 directives that surround the HEAD, list of attached CSS files, footer area, etc. You can then use those directives in your own templates for finer control. Or just [see the "Templates" section here for examples](https://pythonhosted.org/Flask-Bootstrap/basic-usage.html) of how to set up a Flask template that uses Bootstrap.
0 commit comments