Lesson 3: Developing with frameworks
Overview
- Frameworks
- databse
- Templates
- url_for
- forms
- message
- flashing
- JSON
- Styling
Flask: First App
A quick tutorial on decorators:
http://simeonfranklin.com/blog/2012/jul/1/python-decorators-in-12-steps/
from flask import Flask
app = Flask(__name__)
@app.route('/')
@app.route('/hello')
def HelloWorld():
return "Hello World"
if __name__ == '__main__':
app.debug = True
app.run(host = '0.0.0.0', port = 5000)
Adding Database
from flask import Flask
app = Flask(__name__)
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
form database_setup import Base, Restaurant, MenuItem
engine = create_engine('sqlite:///restaurantmenu.db')
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()
@app.route('/')
@app.route('/hello')
def HelloWorld():
restaurant = session.query(Restaurant).first()
items = session.query(MenuItem).filter_by(restaurant_id = restaurant.id)
output = ''
for i in items:
output += i.name
output += '</br>'
return output
if __name__ == '__main__':
app.debug = True
app.run(host = '0.0.0.0', port = 5000)
- Note: before doing these, you need to have
database_setup.py
andlotsofmenus.py
in your folder and run them.
Routing
Flask Documentation on Routing : http://flask.pocoo.org/docs/0.10/quickstart/#routing>
@app.route('/restaurants/<int:restaurant_id>/')
Designing routes with flask
Download the starter template for this code in the instructor notes. Note that there are functions called newMenuItem
, editMenuItem
, and deleteMenuItem
with the parameters they each take in.
Write the appropriate route decorators to properly execute these functions.
The template code:
Templates
Rendering templates
render_templete(templateName.html, variable = keyword)
<html>
<body>
<h1>{{restaurant.name}}</h1>
{% for i in items %}
<div>
<p>{{i.name}}</p>
<p>{{i.description}}</p>
<p> {{i.price}} </p>
</div>
{% endfor %}
</body>
</html>
Resources
HTML Character Escaping is a way of writing special characters inside of HTML code.
http://en.wikipedia.org/wiki/HTML#Character_and_entity_references
Generate URL
...
<a href='{{url_for('editMenuItem', restaurant_id = restaurant.id, menu_id = i.id) }}'>Edit</a>
</br>
<a href = '{{url_for('deleteMenuItem', restaurant_id = restaurant.id, menu_id = i.id ) }}'>Delete</a>
...
Form Requests and Redirects
# Task 1: Create route for newMenuItem function
@app.route('/restaurants/<int:restaurant_id>/new', methods = ['GET', 'post'])
def newMenuItem(restaurant_id):
return "page to create a new menu item. Task 1 complete!"
# Task 2: Create route for editMenuItem function here
@app.route('/restaurant/<int:restaurant_id>/<int:menu_id>/edit/')
def editMenuItem(restaurant_id, menu_id):
return "page to edit a new menu item. Task 2 complete!"
# Task 3: Create a route for deleteMenuItem function here
@app.route('('/restaurant/<int:restaurant_id>/<int:menu_id>/delete/'')
def deleteMenuItem(restaurant_id, menu_id):
return "page to delete a new menu item. Task 3 complete!"
newmenuitem.html
<html>
<body>
<h1> New Menu Item </h1>
<form action="{{url_for('newMenuItem', restaurant_id=restaurant_id )}}" method = 'POST'>
<p>Name:</p>
<input type='text' size='30' name='name'>
<input type='submit' value='Create'>
</form>
</body>
</html>
Task 1 newMenuItem
from flask import Flask, render_templete, request, redirect, url_for
...
# Task 1:
...
def newMenuItem(restaurant_id):
if request.method == 'POST':
newItem = MenuItem(name = request.form['name'], restaurant_id = restaurant_id)
session.add(newItem)
session.commit()
return redirect(url_for('restaurantMenu', restaurant_id = restaurant_id))
else:
return render_templete('newMenuitem.html', restaurant_id = restaurant_id)
Task 2 editMenuItem
# Taks 2:
...
def editMenuItem(restaurant_id, menu_id):
if
Task 3 deleteMenuItem
# Task 3:
...
def deleteMenuItem(restaurant_id, menu_id):
if
Message Flashing
Message flashing is a feature that will prompt a message to the user immediately, after a certain action has taken place, and then disappear the next time the page is requested.
from flask import Flask, render_templete, request, redirect, url_for
...
flash()
if__name__ == '__main__':
app.secret_key = 'super_secret_key'
app.debug = True
app.run(host = '0.0.0.0', port =5000)
in the html file, add with messages
...
<body>
<h1>{{ restaurant.name }}</h1h1>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for massage in messages %}
<li> <strong> {{ message}} </strong> </li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
...
Styling
CSS file:
https://github.com/udacity/Full-Stack-Foundations/tree/master/Lesson-3/18_Styling
JSON
API: Application Programming Interface
RESTful: Representational State Transfer
JSON: JavaScript Object Notation
from flask import jsonify
Making and API Endpoint (GET Request)
@app.route('/restaurants/<int:restaurant_id>/menu/JSON')
def restaurantMenuJSON(restaurant_id):
restaurant = session.query(Restaurant).filter_by(id = restaurant_id).one()
item = session.query(MenuItem).filter_by(restaurant_id = restaurant_id).all()
return jsonify(MenuItems = [i.serialize for i in items])
https://github.com/udacity/Full-Stack-Foundations/tree/master/Lesson-3/19_Responding-with-JSON