diff --git a/hw6/.app.db b/hw6/.app.db new file mode 100644 index 0000000..e69de29 diff --git a/hw6/.app.db; b/hw6/.app.db; new file mode 100644 index 0000000..e69de29 diff --git a/hw6/add.db b/hw6/add.db new file mode 100644 index 0000000..e69de29 diff --git a/hw6/app.db b/hw6/app.db new file mode 100755 index 0000000..1c26c66 Binary files /dev/null and b/hw6/app.db differ diff --git a/hw6/app/__init__.py b/hw6/app/__init__.py new file mode 100755 index 0000000..353d3af --- /dev/null +++ b/hw6/app/__init__.py @@ -0,0 +1,8 @@ +from flask import Flask +from flask.ext.sqlalchemy import SQLAlchemy + +app = Flask(__name__) +app.config.from_object('config') +db = SQLAlchemy(app) + +from app import views, models diff --git a/hw6/app/forms.py b/hw6/app/forms.py new file mode 100755 index 0000000..0c5bd98 --- /dev/null +++ b/hw6/app/forms.py @@ -0,0 +1,27 @@ +from flask.ext.wtf import Form +from wtforms import StringField, IntegerField, SelectMultipleField +from flask_wtf.html5 import EmailField +from wtforms.validators import DataRequired + + +class CustomerForm(Form): + company = StringField('company', validators=[DataRequired()]) + firstName = StringField('firstName', validators=[DataRequired()]) + lastName = StringField('lastName', validators=[DataRequired()]) + email = EmailField('email', validators=[DataRequired()]) + phone = IntegerField('phone', validators=[DataRequired()]) + # Add additional Address fields here + + +class AddressForm(Form): + streetAddress = StringField('streetAddress', validators=[DataRequired()]) + city = StringField('city', validators=[DataRequired()]) + state = StringField('state', validators=[DataRequired()]) + country = StringField('country', validators=[DataRequired()]) + zipCode = IntegerField('zipCode', validators=[DataRequired()]) + + +class OrderForm(Form): + totalSpent = IntegerField('totalSpent', validators=[DataRequired()]) + numPartsOrdered = IntegerField('numPartsOrdered', validators=[DataRequired()]) + customers = SelectMultipleField('customers', coerce=str) diff --git a/hw6/app/models.py b/hw6/app/models.py new file mode 100755 index 0000000..d5d2290 --- /dev/null +++ b/hw6/app/models.py @@ -0,0 +1,42 @@ +from app import db + + +customerOrderRelation = db.Table('customerOrderRelation', + db.Column('customer', db.String, db.ForeignKey('customer.company'), nullable=False), + db.Column('order_id', db.Integer, db.ForeignKey('order.id'), nullable=False), + db.PrimaryKeyConstraint('customer', 'order_id')) + + +class Customer(db.Model): + id = db.Column(db.Integer, primary_key=True) + company = db.Column(db.String(120)) + email = db.Column(db.String(120)) + firstName = db.Column(db.String(120)) + lastName = db.Column(db.String(120)) + phone = db.Column(db.String(10)) + # You need to a relationship to Address table here + # see http://flask-sqlalchemy.pocoo.org/2.1/models/#one-to-many-relationships + addresses = db.relationship('Address', backref='Customer', lazy='dynamic') + orders = db.relationship('Order', backref='Customer', secondary=customerOrderRelation) + + def __repr__(self): + return '' % self.company + + +class Address(db.Model): + id = db.Column(db.Integer, primary_key=True) + streetAddress = db.Column(db.String(120)) + city = db.Column(db.String(120)) + state = db.Column(db.String(120)) + country = db.Column(db.String(120)) + zipCode = db.Column(db.String(5)) + customer_name = db.Column(db.Integer, db.ForeignKey('customer.company')) + + def __repr__(self): + return '
' % (self.streetAddress, self.city, self.state, self.country, self.zipCode) + + +class Order(db.Model): + id = db.Column(db.Integer, primary_key=True) + totalSpent = db.Column(db.Integer) + numPartsOrdered = db.Column(db.Integer) diff --git a/hw6/app/templates/add.html b/hw6/app/templates/add.html new file mode 100755 index 0000000..d47a5fd --- /dev/null +++ b/hw6/app/templates/add.html @@ -0,0 +1,34 @@ +{% extends "base.html" %} +{% block content %} +
+
+
+ Home +
+

Add Customer to Our Database

+
+ {{ form.hidden_tag() }} +
+
+

+ Company name:
+ {{ form.company(size=120) }}
+ Contact first name: + {{ form.firstName(size=120) }}
+ Contact last name: + {{ form.lastName(size=120) }}
+ Contact phone:
+ {{ form.phone(size=10) }}
+ Contact email:
+ {{ form.email(size=120) }}
+

+
+
+
+ +
+

+
+
+
+{% endblock %} diff --git a/hw6/app/templates/add_address.html b/hw6/app/templates/add_address.html new file mode 100644 index 0000000..df0df51 --- /dev/null +++ b/hw6/app/templates/add_address.html @@ -0,0 +1,34 @@ +{% extends "base.html" %} +{% block content %} +
+
+
+ Home +
+

Add Address for client {{ company }}

+
+ {{ form.hidden_tag() }} +
+
+

+ Street Address:
+ {{ form.streetAddress(size=120) }}
+ City: + {{ form.city(size=120) }}
+ State: + {{ form.state(size=120) }}
+ Country:
+ {{ form.country(size=120) }}
+ Zip Code:
+ {{ form.zipCode(size=5) }}
+

+
+
+
+ +
+

+
+
+
+{% endblock %} diff --git a/hw6/app/templates/add_order.html b/hw6/app/templates/add_order.html new file mode 100644 index 0000000..0464b31 --- /dev/null +++ b/hw6/app/templates/add_order.html @@ -0,0 +1,30 @@ +{% extends "base.html" %} +{% block content %} +
+
+
+ Home +
+

Create New Order

+
+ {{ form.hidden_tag() }} +
+
+

+ Total Amount Spent:
+ {{ form.totalSpent }}
+ Number of Parts Ordered: + {{ form.numPartsOrdered }}
+ Customers:
+ {{ form.customers(style='display:initial; height:initial') }}
+

+
+
+
+ +
+

+
+
+
+{% endblock %} diff --git a/hw6/app/templates/base.html b/hw6/app/templates/base.html new file mode 100755 index 0000000..2f4a3a2 --- /dev/null +++ b/hw6/app/templates/base.html @@ -0,0 +1,15 @@ + + + + {% if title %} + {{ title }} - ACME + {% else %} + Welcome to ACME Aircraft Parts + {% endif %} + + + + + {% block content %}{% endblock %} + + diff --git a/hw6/app/templates/each.html b/hw6/app/templates/each.html new file mode 100644 index 0000000..d5d806f --- /dev/null +++ b/hw6/app/templates/each.html @@ -0,0 +1,53 @@ +{% extends "base.html" %} +{% set title = "More Info" %} +{% block content %} +
+
+

All about {{ customer.company }}

+
+ Home +
+
+
+ + + + + + +
Company Name{{ customer.company }}
Contact First Name{{ customer.firstName }}
Contact Last Name{{ customer.lastName }}
Contact Phone{{ customer.phone }}
Contact Email{{ customer.email }}
+ {% for address in customer.addresses %} +

Address {{ loop.index }}

+
+
+ + + + + + +
Street Address{{ address.streetAddress }}
City{{ address.city }}
State{{ address.state }}
Country{{ address.country }}
Zip Code{{ address.zipCode }}
+ {% endfor %} +

Procured Order

+
+
+ + + + + + + + + {% for order in customer.orders %} + + + + + + {% endfor %} +
Order NumberOrder AmountNumber of Parts Ordered
{{ order.id }}{{ order.totalSpent }}{{ order.numPartsOrdered }}
+
+
+
+{% endblock %} diff --git a/hw6/app/templates/home.html b/hw6/app/templates/home.html new file mode 100755 index 0000000..26b9ebb --- /dev/null +++ b/hw6/app/templates/home.html @@ -0,0 +1,57 @@ +{% extends "base.html" %} +{% set title = "customers' listing" %} +{% block content %} +
+
+

Welcome to ACME Aircraft Parts

+
+

Our Awesome Customers:

+ + + + + + + + + {% for customer in customers %} + + + + + + {% endfor %} +
CompanyDetailsAddresses
{{ customer.company }}viewadd
+
+ +

Our Proud Orders:

+ + + + + + + + + {% for order in orders %} + + + + + + {% endfor %} +
Order Total AmountOrder DetailsOrder Customers
{{ order.id }}view + {% for customer in order.Customer %} + {{ customer.company }} + {% endfor %} +
+
+ +
+
+
+{% endblock %} diff --git a/hw6/app/templates/order.html b/hw6/app/templates/order.html new file mode 100644 index 0000000..54f5bc8 --- /dev/null +++ b/hw6/app/templates/order.html @@ -0,0 +1,29 @@ +{% extends "base.html" %} +{% set title = "More Info" %} +{% block content %} +
+
+

All About Order No.{{ order.id }}

+
+ Home +
+
+
+ + + + +
Order No.{{ order.id }}
Total Procured Amount{{ order.totalSpent }}
Number of Parts Ordered{{ order.numPartsOrdered }}
+
+

Procuring Customers

+
+
+ + {% for customer in order.Customer %} + + {% endfor %} +
{{ customer.company }}
+
+
+
+{% endblock %} diff --git a/hw6/app/views.py b/hw6/app/views.py new file mode 100755 index 0000000..746217c --- /dev/null +++ b/hw6/app/views.py @@ -0,0 +1,88 @@ +from flask import render_template, redirect, request, url_for +from app import app, models, db +from .forms import CustomerForm, AddressForm, OrderForm + + +@app.route('/') +def index(): + return redirect('/home') + + +@app.route('/home') +def display_customer(): + customers = models.Customer.query.all() + orders = models.Order.query.all() + return render_template('home.html', customers=customers, orders=orders) + + +@app.route('/customers/') +def each_customer(company): + customer = models.Customer.query.filter_by(company=company).first_or_404() + return render_template('each.html', customer=customer) + + +@app.route('/order/') +def order(id): + order = models.Order.query.filter_by(id=id).first_or_404() + return render_template('order.html', order=order) + + +@app.route('/add', methods=['GET', 'POST']) +def add(): + form = CustomerForm() + if form.validate_on_submit(): + print("yo") + customer = models.Customer( + company=form.company.data, + firstName=form.firstName.data, + lastName=form.lastName.data, + phone=form.phone.data, + email=form.email.data, + ) + db.session.add(customer) + db.session.commit() + return redirect('/home') + else: + print('what') + return render_template('add.html', form=form) + + +@app.route('/add_address', methods=['GET', 'POST']) +def add_address(): + form = AddressForm() + company = request.args.get('company') + if form.validate_on_submit(): + print('yo') + print(company) + address = models.Address( + streetAddress=form.streetAddress.data, + city=form.city.data, + state=form.state.data, + country=form.country.data, + zipCode=form.zipCode.data, + customer_name=company + ) + db.session.add(address) + db.session.commit() + return redirect(url_for('each_customer', company=company)) + return render_template('add_address.html', form=form) + + +@app.route('/add_order', methods=['GET', 'POST']) +def add_order(): + form = OrderForm() + # Define the choices for the OrderForm's customers (a SelectMultipleField) + form.customers.choices = [(c.company, c.company) for c in models.Customer.query.all()] + if form.validate_on_submit(): + print(form.customers.data) + order = models.Order( + totalSpent=form.totalSpent.data, + numPartsOrdered=form.numPartsOrdered.data, + ) + for i in form.customers.data: + target = models.Customer.query.filter_by(company=i).first() + order.Customer.append(target) + db.session.add(order) + db.session.commit() + return redirect(url_for('display_customer')) + return render_template('add_order.html', form=form) diff --git a/hw6/config.py b/hw6/config.py new file mode 100755 index 0000000..a995426 --- /dev/null +++ b/hw6/config.py @@ -0,0 +1,8 @@ +import os +basedir = os.path.abspath(os.path.dirname(__file__)) + +SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.db') +SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository') + +WTF_CSRF_ENABLED = True +SECRET_KEY = 'you-will-never-guess' diff --git a/hw6/readme.md b/hw6/readme.md new file mode 100755 index 0000000..f5a8d70 --- /dev/null +++ b/hw6/readme.md @@ -0,0 +1,21 @@ +# Models Lab/Homework +The goal for this lab is to get you comfortable translating your database models into actual code. We will be using [ORMs](https://en.wikipedia.org/wiki/Object-relational_mapping) to help us. The particular ORM that we will be using is SQLAlchemy (the flask implementation is called [Flask-SQLAlchemy](http://flask-sqlalchemy.pocoo.org/2.1/)). + +We'll walk through the example together in class which will give you an idea of how this all works together. Your goal for this lab and homework is to create the remaining models, forms, and routes to complete v2 of the exercise from last week. + +This means that you must: +* Create the following tables and the appropriate relationships: + * customer + * address + * order + * Remember to run update_database.py whenever you make changes to any models. + * This will update the database with your changes. However, **it will delete any data in the database**. +* Create the forms, templates, routes, etc necessary to input this data into the database. +* Create a view to showcase the data into your database (see the current implementation of "home.html" for example) + +The following documentation will help answer any questions you may have. + +## Helpful Documentation +- [Flask-SQLAlchemy](http://flask-sqlalchemy.pocoo.org/2.1/) +- [Accessing SQLite3 Command Shell](https://www.sqlite.org/cli.html) +- [Flask-WTF](https://flask-wtf.readthedocs.org/en/latest/) (flask plugin for creating forms easily) diff --git a/hw6/requirements.txt b/hw6/requirements.txt new file mode 100755 index 0000000..bfbaf81 --- /dev/null +++ b/hw6/requirements.txt @@ -0,0 +1,10 @@ +Flask==0.10.1 +Flask-SQLAlchemy==2.1 +Flask-WTF==0.12 +itsdangerous==0.24 +Jinja2==2.8 +MarkupSafe==0.23 +SQLAlchemy==1.0.12 +Werkzeug==0.11.4 +wheel==0.29.0 +WTForms==2.1 diff --git a/hw6/run.py b/hw6/run.py new file mode 100755 index 0000000..5d2f714 --- /dev/null +++ b/hw6/run.py @@ -0,0 +1,2 @@ +from app import app +app.run(debug=True, host="0.0.0.0", port=8081) diff --git a/hw6/update_database.py b/hw6/update_database.py new file mode 100755 index 0000000..b15e4da --- /dev/null +++ b/hw6/update_database.py @@ -0,0 +1,3 @@ +from app import db +db.drop_all() +db.create_all()