diff --git a/Procfile b/Procfile index 629b83a..55045da 100644 --- a/Procfile +++ b/Procfile @@ -1 +1 @@ -web: python main.py +web: python main.py diff --git a/README.md b/README.md index 86dc732..09cbadb 100644 --- a/README.md +++ b/README.md @@ -1,62 +1,62 @@ -# Flask Mailroom Application - -Running at [http://afternoon-reef-51666.herokuapp.com/donations/](http://afternoon-reef-51666.herokuapp.com/donations/). - -## Your Task - -Your task is to: - -1. Add a page with a form for CREATING new donations from existing donors in the database: - * The page should have a form, with a field for the donor name and a field for the amount of the donation. - * The method of the form should be POST. - * You will need to create a template for this page, inside of the `templates` directory. The template should inherit from `base.jinja2`. - * You should create a route and a handler function inside of `main.py`. The handler function should accept both GET requests and POST requests. - * If the handler receives a GET request, then it should render the template for the donation creation page. - * If the handler receives a POST request (a form submission), then it should attempt to retrieve the name of the donor and the amount of the donation from the form submission. It should retrieve the donor from the database with the indicated name, and create a new donation with the indicated donor and donation amount. Then it should redirect the visitor to the home page. - -2. Add navigation elements in `base.jinja2` to the top of both pages. The navigation elements should include links to both the home page and your new donation-creation page. - -3. Publish your work to Heroku. If you publish your work to Heroku and then make changes to your application, you will need to publish those changes by commiting your work to your git repository and then executing `git push heroku master`. Make sure that you also `git push origin master` to push your changes to GitHub. - -4. Edit the top of this README file, replacing _my_ Heroku link ([http://afternoon-reef-51666.herokuapp.com/donations/](http://afternoon-reef-51666.herokuapp.com/donations/)) with your own Heroku link. If you're unable to get your application running on Heroku, that's no problem. Instead, just write a couple of sentences about where you got hung up. - - -## Getting Started - -I recommend that you begin by forking this repository into your own account, then cloning it to your computer. Then follow the instructions below to run the program. Once you can see the homepage, including a list of donations by Alice, Bob, and Charlie, then you are ready to make your modifications to the program. - -## To Run - -All commands to be run from inside the repository directory. -``` -$ mkvirtualenv flask-mailroom -$ pip install -r requirements.txt -$ python setup.py -$ python main.py -``` - -Confirm that the application is running on port 6738, and then open your browser to [http://localhost:6738](http://localhost:6738) - -## To Publish to Heroku - -All commands to be run from inside the repository directory. -``` -$ git init # Only necessary if this is not already a git repository -$ heroku create -$ git push heroku master # If you have any changes or files to add, commit them before you push. -$ heroku addons:create heroku-postgresql:hobby-dev -$ heroku run python setup.py -$ heroku open -``` - -## Taking it Further - -Here are some *optional* ways that you can extend your application: - -1. Think about what can go wrong with form submission. What would you like to do if a user enters a name that _does not exist_ in the database of donors? One possibility would be to re-display the donation creation form and inject a message describing the error. Another possibility would be to _create_ a new donor with the given name, along with the indicated donation. Implement either solution. - -2. Allow all visitors to view the page of donations, but require that users _login_ in order to enter a donation. This would involve new pages, new models, changes to the database `setup.py` file, and the use of a secret key to encode values into the session. - -3. Create a page that allows visitors to view all donations from a single donor. You could accomplish this by creating a new page with a form that allows visitors to submit the name of the donor that they would like to see donations for. If the form has been submitted, then the handler function would retrieve that name, find the indicated donor, retrieve all of their donations, and then inject them into the page to be rendered. Ideally, the method of the form would be GET. This extension would include some steps or combinations of code that I may not have demonstrated in the lesson, but that you could probably puzzle out. - -If you choose to perform any of these *optional* extensions, then let us know as a comment to your submission! +# Flask Mailroom Application + +Running at http://mysterious-wave-29356.herokuapp.com/donations/](http://mysterious-wave-29356.herokuapp.com/donations/). + +## Your Task + +Your task is to: + +1. Add a page with a form for CREATING new donations from existing donors in the database: + * The page should have a form, with a field for the donor name and a field for the amount of the donation. + * The method of the form should be POST. + * You will need to create a template for this page, inside of the `templates` directory. The template should inherit from `base.jinja2`. + * You should create a route and a handler function inside of `main.py`. The handler function should accept both GET requests and POST requests. + * If the handler receives a GET request, then it should render the template for the donation creation page. + * If the handler receives a POST request (a form submission), then it should attempt to retrieve the name of the donor and the amount of the donation from the form submission. It should retrieve the donor from the database with the indicated name, and create a new donation with the indicated donor and donation amount. Then it should redirect the visitor to the home page. + +2. Add navigation elements in `base.jinja2` to the top of both pages. The navigation elements should include links to both the home page and your new donation-creation page. + +3. Publish your work to Heroku. If you publish your work to Heroku and then make changes to your application, you will need to publish those changes by commiting your work to your git repository and then executing `git push heroku master`. Make sure that you also `git push origin master` to push your changes to GitHub. + +4. Edit the top of this README file, replacing _my_ Heroku link ([http://afternoon-reef-51666.herokuapp.com/donations/](http://afternoon-reef-51666.herokuapp.com/donations/)) with your own Heroku link. If you're unable to get your application running on Heroku, that's no problem. Instead, just write a couple of sentences about where you got hung up. + + +## Getting Started + +I recommend that you begin by forking this repository into your own account, then cloning it to your computer. Then follow the instructions below to run the program. Once you can see the homepage, including a list of donations by Alice, Bob, and Charlie, then you are ready to make your modifications to the program. + +## To Run + +All commands to be run from inside the repository directory. +``` +$ mkvirtualenv flask-mailroom +$ pip install -r requirements.txt +$ python setup.py +$ python main.py +``` + +Confirm that the application is running on port 6738, and then open your browser to [http://localhost:6738](http://localhost:6738) + +## To Publish to Heroku + +All commands to be run from inside the repository directory. +``` +$ git init # Only necessary if this is not already a git repository +$ heroku create +$ git push heroku master # If you have any changes or files to add, commit them before you push. +$ heroku addons:create heroku-postgresql:hobby-dev +$ heroku run python setup.py +$ heroku open +``` + +## Taking it Further + +Here are some *optional* ways that you can extend your application: + +1. Think about what can go wrong with form submission. What would you like to do if a user enters a name that _does not exist_ in the database of donors? One possibility would be to re-display the donation creation form and inject a message describing the error. Another possibility would be to _create_ a new donor with the given name, along with the indicated donation. Implement either solution. + +2. Allow all visitors to view the page of donations, but require that users _login_ in order to enter a donation. This would involve new pages, new models, changes to the database `setup.py` file, and the use of a secret key to encode values into the session. + +3. Create a page that allows visitors to view all donations from a single donor. You could accomplish this by creating a new page with a form that allows visitors to submit the name of the donor that they would like to see donations for. If the form has been submitted, then the handler function would retrieve that name, find the indicated donor, retrieve all of their donations, and then inject them into the page to be rendered. Ideally, the method of the form would be GET. This extension would include some steps or combinations of code that I may not have demonstrated in the lesson, but that you could probably puzzle out. + +If you choose to perform any of these *optional* extensions, then let us know as a comment to your submission! diff --git a/__pycache__/model.cpython-37.pyc b/__pycache__/model.cpython-37.pyc new file mode 100644 index 0000000..aeeb475 Binary files /dev/null and b/__pycache__/model.cpython-37.pyc differ diff --git a/main.py b/main.py index a7b6794..7113819 100644 --- a/main.py +++ b/main.py @@ -1,23 +1,38 @@ -import os -import base64 - -from flask import Flask, render_template, request, redirect, url_for, session - -from model import Donation - -app = Flask(__name__) - -@app.route('/') -def home(): - return redirect(url_for('all')) - -@app.route('/donations/') -def all(): - donations = Donation.select() - return render_template('donations.jinja2', donations=donations) - - -if __name__ == "__main__": - port = int(os.environ.get("PORT", 6738)) - app.run(host='0.0.0.0', port=port) - +import os +import base64 + +from flask import Flask, render_template, request, redirect, url_for, session + +from model import Donor, Donation + +app = Flask(__name__) + + +@app.route('/') +def home(): + return redirect(url_for('all')) + +@app.route('/donations/') +def all(): + donations = Donation.select() + return render_template('donations.jinja2', donations=donations) + + +@app.route('/create', methods=['GET', 'POST']) +def create(): + if request.method == 'GET': + return render_template('create.jinja2') + + if request.method == 'POST': + donor = Donor.select().where(Donor.name == request.form['name']).get() + donation = Donation(donor=donor, value=int(request.form['value'])) + donation.save() + + return redirect(url_for('home')) + else: + return render_template('create.jinja2') + +if __name__ == "__main__": + port = int(os.environ.get("PORT", 6738)) + app.run(host='0.0.0.0', port=port) + diff --git a/model.py b/model.py index baa7e50..dab7e2f 100644 --- a/model.py +++ b/model.py @@ -1,20 +1,20 @@ -import os - -from peewee import Model, CharField, IntegerField, ForeignKeyField -from playhouse.db_url import connect - -db = connect(os.environ.get('DATABASE_URL', 'sqlite:///my_database.db')) - -class Donor(Model): - name = CharField(max_length=255, unique=True) - - class Meta: - database = db - -class Donation(Model): - value = IntegerField() - donor = ForeignKeyField(Donor, backref='donations') - - class Meta: - database = db - +import os + +from peewee import Model, CharField, IntegerField, ForeignKeyField +from playhouse.db_url import connect + +db = connect(os.environ.get('DATABASE_URL', 'sqlite:///my_database.db')) + +class Donor(Model): + name = CharField(max_length=255, unique=True) + + class Meta: + database = db + +class Donation(Model): + value = IntegerField() + donor = ForeignKeyField(Donor, backref='donations') + + class Meta: + database = db + diff --git a/my_database.db b/my_database.db new file mode 100644 index 0000000..a261f59 Binary files /dev/null and b/my_database.db differ diff --git a/requirements.txt b/requirements.txt index c8351ab..5f83955 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ -click==6.7 -Flask==0.12.3 -itsdangerous==0.24 -Jinja2==2.10 -MarkupSafe==1.0 -peewee==3.2.2 -psycopg2==2.7.4 -Werkzeug==0.14.1 +click==6.7 +Flask==0.12.3 +itsdangerous==0.24 +Jinja2==2.10 +MarkupSafe==1.0 +peewee==3.2.2 +psycopg2==2.7.4 +Werkzeug==0.14.1 diff --git a/setup.py b/setup.py index 8854a12..33254be 100644 --- a/setup.py +++ b/setup.py @@ -1,26 +1,26 @@ -import random - -from model import db, Donor, Donation - -db.connect() - -# This line will allow you "upgrade" an existing database by -# dropping all existing tables from it. -db.drop_tables([Donor, Donation]) - -db.create_tables([Donor, Donation]) - -alice = Donor(name="Alice") -alice.save() - -bob = Donor(name="Bob") -bob.save() - -charlie = Donor(name="Charlie") -charlie.save() - -donors = [alice, bob, charlie] - -for x in range(30): - Donation(donor=random.choice(donors), value=random.randint(100, 10000)).save() - +import random + +from model import db, Donor, Donation + +db.connect() + +# This line will allow you "upgrade" an existing database by +# dropping all existing tables from it. +db.drop_tables([Donor, Donation]) + +db.create_tables([Donor, Donation]) + +alice = Donor(name="Alice") +alice.save() + +bob = Donor(name="Bob") +bob.save() + +charlie = Donor(name="Charlie") +charlie.save() + +donors = [alice, bob, charlie] + +for x in range(30): + Donation(donor=random.choice(donors), value=random.randint(100, 10000)).save() + diff --git a/templates/base.jinja2 b/templates/base.jinja2 index f10648b..112f066 100644 --- a/templates/base.jinja2 +++ b/templates/base.jinja2 @@ -1,10 +1,10 @@ - -
-