{"id":17834670,"url":"https://github.com/bendog/shecodes_flask_demo","last_synced_at":"2026-03-19T02:10:07.679Z","repository":{"id":53639794,"uuid":"250241402","full_name":"bendog/shecodes_flask_demo","owner":"bendog","description":"Demo on how to make a really simple to follow flask website that focuses on learning over \"doing it right\"","archived":false,"fork":false,"pushed_at":"2022-09-16T18:25:14.000Z","size":43,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-18T18:02:45.714Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bendog.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-26T11:35:59.000Z","updated_at":"2020-03-26T12:41:56.000Z","dependencies_parsed_at":"2023-01-18T13:01:09.528Z","dependency_job_id":null,"html_url":"https://github.com/bendog/shecodes_flask_demo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bendog/shecodes_flask_demo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bendog%2Fshecodes_flask_demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bendog%2Fshecodes_flask_demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bendog%2Fshecodes_flask_demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bendog%2Fshecodes_flask_demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bendog","download_url":"https://codeload.github.com/bendog/shecodes_flask_demo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bendog%2Fshecodes_flask_demo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271035378,"owners_count":24688396,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-18T02:00:08.743Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-27T20:09:29.487Z","updated_at":"2025-10-17T13:13:40.160Z","avatar_url":"https://github.com/bendog.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Shecodes Flask Demo\n\nSimplified demo of Flask\n\n- [install dependences](#install-dependences)\n- [shell / pipenv commands](#shell--pipenv-commands)\n  - [install](#install)\n  - [run](#run)\n  - [setup database](#setup-database)\n  - [make migrations](#make-migrations)\n  - [apply migrations](#apply-migrations)\n- [notable changes](#notable-changes)\n- [process of creating app.py](#process-of-creating-apppy)\n  - [**stage one:** show something](#stage-one-show-something)\n  - [**stage two:** show something pretty](#stage-two-show-something-pretty)\n  - [**stage three:** show more things](#stage-three-show-more-things)\n  - [**stage four:** create the database](#stage-four-create-the-database)\n    - [add packages with pipenv](#add-packages-with-pipenv)\n    - [setting up our flask database](#setting-up-our-flask-database)\n    - [defining our database model](#defining-our-database-model)\n    - [reading from the database model](#reading-from-the-database-model)\n    - [initialise, migrate and upgrade the database](#initialise-migrate-and-upgrade-the-database)\n  - [**stage five:**  adding data to the database.](#stage-five--adding-data-to-the-database)\n\n---\n\n## install dependences\n\nYou'll need python 3.8\n\nYou'll need to install pipenv to create your virtual environment, to enable the .env file for the environment variable settings, and also to run the commands to run flask.\n\ninstalling pipenv is as easy as\n- `sudo pip3 install pipenv` (on mac)\n- `pip install pipenv` (on windows)\n\n## shell / pipenv commands\n\n### install\n\n    pipenv install\n\n### run\n\n    pipenv run flask run\n\n### setup database\n\n    pipenv run flask db init\n\n### make migrations\n\n    pipenv run flask db migrate\n\n### apply migrations\n\n    pipenv run flask db upgrade\n\n## notable changes\n\n1. use app.py as a name, as it avoids having to introduce the concept of environmental variables\n1. avoid blueprints, as we don't need to introduce the concept of multi-app tenancy to beginners\n1. using pipenv, as it will load a .env file and have the same commands on windows, mac and linux.\n1. add a way to add data to the database via a website, this was more exciting than using a form somewhere else\n1. decided to use just one python file, as it makes it easier to conceptualise what's going on\n\n## process of creating app.py\n\n### **stage one:** show something\n\ninstall flask\n\n    $ pipenv --three\n    ... creating\n    $ pipenv install flask\n    ... installing\n\ncreate the environment file\n\n`.env`\n```shell\nFLASK_ENV=development\n```\n\ncreate the app\n\n` app.py`\n```python\nfrom flask import Flask\n\napp = Flask(__name__)\n\n@app.route('/')\ndef index():\n    return \"hello world\"\n\n\n# start the server with the 'run()' method\nif __name__ == '__main__':\n    app.run(debug=True)\n```\n\nrun flask\n\n    $ pipenv run flask run\n    ... running \n\n### **stage two:** show something pretty\n\ncopy in templates directory and files\n\nedit `app.py`\n\n```python\nfrom flask import Flask, render_templates\n\napp = Flask(__name__)\n\n@app.route('/')\ndef index():\n    return render_template('index.html')\n\n\n# start the server with the 'run()' method\nif __name__ == '__main__':\n    app.run(debug=True)\n```\n\n### **stage three:** show more things\n\nedit `app.py`\n```python\nfrom flask import Flask, render_templates\n\napp = Flask(__name__)\n\n@app.route('/')\ndef index():\n    # return to template\n    return render_template(\n        'index.html', # which template\n        # all the variables for context go here\n        projects=[\n            {'name': 'day 1', 'description': 'html/css'},\n            {'name': 'day 2', 'description': 'python!'},\n            {'name': 'day 3', 'description': 'flask'},\n        ],\n    )\n\n@app.route('/contact')\ndef contact():\n    return render_template('contact.html')\n\n@app.route('/about')\ndef about():\n    return render_template('about.html')\n\n\n# start the server with the 'run()' method\nif __name__ == '__main__':\n    app.run(debug=True)\n```\n\ntalk about how templates work:\n\n- context values\n- loops\n- include\n- extend\n\n### **stage four:** create the database\n\nthere's a lot of bits that need to be added here, most of this can be copy paste, but it's good to walk through.\n\n#### add packages with pipenv\n\n    $ pipenv install flask-sqlalchemy\n    ... installing\n    $ pipenv install flask-migrate\n    ... installing\n\nnext we edit `app.py`, i'm going to do this in stages starting from the top.\n\n#### setting up our flask database\n\n```python\nimport os\nfrom flask import Flask, render_template, request, redirect, url_for\nfrom flask_sqlalchemy import SQLAlchemy\nfrom flask_migrate import Migrate\n\n\n##########\n# config\n##########\n\n\nBASEDIR = os.path.abspath(os.path.dirname(__file__))\n\nclass Config(object):\n    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(BASEDIR, 'app.sqlite')\n    SQLALCHEMY_TRACK_MODIFICATIONS = False\n\n\napp = Flask(__name__)\napp.config.from_object(Config)\ndb = SQLAlchemy(app)\nmigrate = Migrate(app, db)\n\n...\n```\n\nWe have to add a lot of config to our project to get the database working.\n\n- we need to import SQLAlchemy and Migrate\n- we need to configure where the database will be found\n- then we need to bind the database to our flask app\n\n#### defining our database model\n\nI've chosen to do this in the same file, rather than creating a models.py file, because, we're aiming for absolute beginners, multiple files is just difficult to make sure everyone is editing the same file.\n\n```python\n\n...\n# after migrate\n\n# our project table\nclass Project(db.Model):\n    id = db.Column(db.Integer, primary_key=True)\n    name = db.Column(db.String(255), index=True, unique=True)\n    description = db.Column(db.Text())\n\n\n# before app.route('/')\n...\n```\n\nthis is our table for our projects.\n\n#### reading from the database model\n\nthis is pretty simple, we just make our \n\n```python\n...\n@app.route('/')\ndef index():\n    # # get the data\n    all_projects= Project.query.all()\n    # return to template\n    return render_template(\n        'index.html', # which template\n        # all the variables for context go here\n        all_projects=all_projects\n    )\n...\n```\n\n#### initialise, migrate and upgrade the database\n\n    $ pipenv run flask db init\n    Creating directory /Users/bendog/dev/shecodes_flask_demo/migrations ...  done\n    Creating directory /Users/bendog/dev/shecodes_flask_demo/migrations/versions ...  done\n    Generating /Users/bendog/dev/shecodes_flask_demo/migrations/script.py.mako ...  done\n    Generating /Users/bendog/dev/shecodes_flask_demo/migrations/env.py ...  done\n    Generating /Users/bendog/dev/shecodes_flask_demo/migrations/README ...  done\n    Generating /Users/bendog/dev/shecodes_flask_demo/migrations/alembic.ini ...  done\n    Please edit configuration/connection/logging settings in '/Users/bendog/dev/shecodes_flask_demo/migrations/alembic.ini' before proceeding.\n\n    $ pipenv run flask db migrate\n    INFO  [alembic.runtime.migration] Context impl SQLiteImpl.\n    INFO  [alembic.runtime.migration] Will assume non-transactional DDL.\n    INFO  [alembic.autogenerate.compare] Detected added table 'project'\n    INFO  [alembic.autogenerate.compare] Detected added index 'ix_project_name' on '['name']'\n    Generating /Users/bendog/dev/shecodes_flask_demo/migrations/versions/1994ef3acb05_.py ...  done\n\n    $ pipenv run flask db upgrade\n    INFO  [alembic.runtime.migration] Context impl SQLiteImpl.\n    INFO  [alembic.runtime.migration] Will assume non-transactional DDL.\n    INFO  [alembic.runtime.migration] Running upgrade  -\u003e 1994ef3acb05, empty message\n\n    $ pipenv run flask run\n\nafter running these commands, flask should be running again and happy, however there's no data in the database, so lets add a way to add data.\n\n### **stage five:**  adding data to the database.\n\ncreate a new html template\n\n`update.html`\n```html\n{% extends 'base.html' %}\n\n{% block heading %}\n    \u003ch1\u003eUpdate Project\u003c/h1\u003e\n{% endblock %}\n\n{% block content %}\n\u003cform  method=\"POST\" action=\"\"\u003e\n    \u003cinput type=\"text\" name=\"name\" placeholder=\"Project name\"\u003e\n    \u003ctextarea name=\"description\" placeholder=\"Project description\"\u003e\u003c/textarea\u003e\n    \u003cbutton type=\"submit\"\u003eSend Message\u003c/button\u003e\n\u003c/form\u003e\n{% endblock %}\n```\n\nupdate `nav.html`\n```html\n\u003cnav\u003e\n    \u003ca href=\"{{ url_for('index') }}\"\u003eHome\u003c/a\u003e\n    \u003ca href=\"{{ url_for('about') }}\"\u003eAbout\u003c/a\u003e\n    \u003ca href=\"{{ url_for('contact') }}\"\u003eContact\u003c/a\u003e\n    \u003ca href=\"{{ url_for('update') }}\"\u003eUpdate\u003c/a\u003e\n\u003c/nav\u003e\n```\n\nnow add a new route to `app.py`\n```python\n...\n\n@app.route('/update', methods=['GET', 'POST'])\ndef update():\n    # get the data from the form\n    if request.form:\n        data = request.form\n        # get the name\n        name = data['name']\n        print('name:', name)\n        # get the description\n        description = data['description']\n        print('description:', description)\n\n        # put the data in the database\n        new_project = Project(name=name, description=description)\n        db.session.add(new_project)\n        db.session.commit()\n        \n        # redirect to home\n        return redirect(url_for(\"index\"), code=303)\n\n    return render_template('update.html')\n\n...\n```\n\nnow our students can use a form to add new content to their index page, they get to see the joy of taking in data and seeing it change their page before their eyes!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbendog%2Fshecodes_flask_demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbendog%2Fshecodes_flask_demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbendog%2Fshecodes_flask_demo/lists"}