Web Programming I (Python) 2021 (Routing, Form)
Web Programming I (Python) 2021 (Routing, Form)
Lecture 03
Learning Outcomes
After Completing this lesson, you should be able to explain how to
@app.route('/user/<username>')
def show_user_profile(username):
# show the user profile for that user
return 'User %s' % escape(username)
Routing
Use the route() decorator to bind a view function to a URL
@app.route('/')
def index():
return render_template('index.html')
@app.route('/todo/<int:id>')
def show_todo(id):
todos = {0: 'Studying', 1: 'Shopping'}
return todos[id]
Routing: Variable Rules
You can use a converter to specify the type of the argument like
<converter:variable_name>
Converter Types
string
(default) accepts any text without a path
slash like string but also accepts
int slashes
accepts positive integers uuid
float accepts UUID strings
accepts positive floating point values
Routing: Variable Rules
You can use a converter to specify the type of the argument like
<converter:variable_name>
@app.route('/path/<path:subpath>')
def show_subpath(subpath):
# show the subpath after /path/
return 'Subpath %s' % escape(subpath)
URL Building
To build a URL to a specific function, use the url_for() function
It accepts the name of the view function as its first argument and any
number of keyword arguments, each corresponding to a variable part of the
URL rule
To generate URLs for static files, use the special 'static' endpoint name in
the url_for() function
url_for('static', filename='style.css')
Extract the javascript and css files and put them inside the
static folder as shown
Integrating Bootstrap CSS framework
Inside your base.html file you can import the CSS and JS files as shown
below
Errors
If you want to use custom error page, you can use the errorhandler()
decorator
@app.errorhandler(404)
def page_not_found(error):
return render_template('page_not_found.html'), 404
HTTP Methods
By default, a route only answers to GET requests
You can use the methods argument of the route() decorator to handle
different HTTP methods
from flask import request
@app.route('/')
def index():
return redirect(url_for('login'))
Responses
The return value from a view function is automatically converted into a
response object for you
If you want to get hold of the resulting response object inside the view you
can use the make_response() function
@app.errorhandler(404)
def not_found(error):
resp = make_response(render_template('page_not_found.html'), 404)
resp.headers['X-Something'] = 'A value'
return resp
Working with Form
WTForms Library
Installation
Example
Let us create a form for accepting todo task information from a user
Sample Code
https://github.com/betsegawlemma/flask-wtf-form-with-bootstrap
Working with Form
Step - 1: Create a form class (inside forms.py file, for example) by extending
the FlaskForm class and by using field type classes from wtforms package
class TaskForm(FlaskForm):
title = StringField('Title')
due_date = StringField('Due Date')
submit = SubmitField('Submit')
Working with Form
Step - 2: Define a route, a view function and pass an instance of the form class
to the template from flask import Flask, render_template
from forms import TaskForm
Required for
CSRF protection app = Flask(__name__)
app.config['SECRET_KEY']='7ff61fae7049489'
@app.route('/todo')
def todo():
form = TaskForm()
return render_template('todo.html', form = form)
Working with Form
Step - 3: Define the View using form fields
<form method='POST' style="width: 20em;">
{{ form.csrf_token }}
<div class="form-group">
{{ form.title.label(class='form-control-label') }}
{{ form.title(class='form-control') }}
</div>
<div class="form-group">
{{ form.due_date.label(class='form-control-label') }}
{{ form.due_date(class='form-control') }}
</div>
{{ form.submit(class='btn btn-primary')}}
</form>
Working with Form
Step - 4: Processing Form Data
todos = []
@app.route('/todo', methods=['GET','POST'])
def todo():
form = TaskForm()
if form.validate_on_submit():
todos.append({'title': form.title.data,
'due_date': form.due_date.data})
class TaskForm(FlaskForm):
title = StringField('Title', validators=[DataRequired()])
due_date = StringField('Due Date')
submit = SubmitField('Submit')
Working with Form
Step - 5: Validation title field
<div class="form-group">
{{ form.title.label(class='form-control-label') }}
{% if form.title.errors %}
{{ form.title(class='form-control is-invalid') }}
<div class="invalid-feedback">
{% for error in form.title.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.title(class='form-control') }}
{% endif %}
</div>
References
https://flask.palletsprojects.com/en/1.1.x/quickstart/
https://flask-wtf.readthedocs.io/en/stable/index.html
https://getbootstrap.com/