├── .gitignore
├── Image-1.PNG
├── Image-2.PNG
├── Image-3.PNG
├── Image-4.PNG
├── Image-5.PNG
├── Image-6.PNG
├── Image-7.PNG
├── Image-8.PNG
├── Procfile
├── README.md
├── app
├── __init__.py
├── flaskcrud.db
├── module
│ ├── __init__.py
│ ├── controller.py
│ └── models.py
└── templates
│ ├── form-update.html
│ └── home.html
├── requirements.txt
└── run.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by https://www.gitignore.io/api/osx,venv,macos,linux,python,django,pycharm,virtualenv
2 |
3 | ### Django ###
4 | __pycache__/
5 | venv/
6 | .idea
--------------------------------------------------------------------------------
/Image-1.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piinalpin/flask-crud/a016109745c8b144c46a3e6d6eb25ebbccfdb270/Image-1.PNG
--------------------------------------------------------------------------------
/Image-2.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piinalpin/flask-crud/a016109745c8b144c46a3e6d6eb25ebbccfdb270/Image-2.PNG
--------------------------------------------------------------------------------
/Image-3.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piinalpin/flask-crud/a016109745c8b144c46a3e6d6eb25ebbccfdb270/Image-3.PNG
--------------------------------------------------------------------------------
/Image-4.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piinalpin/flask-crud/a016109745c8b144c46a3e6d6eb25ebbccfdb270/Image-4.PNG
--------------------------------------------------------------------------------
/Image-5.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piinalpin/flask-crud/a016109745c8b144c46a3e6d6eb25ebbccfdb270/Image-5.PNG
--------------------------------------------------------------------------------
/Image-6.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piinalpin/flask-crud/a016109745c8b144c46a3e6d6eb25ebbccfdb270/Image-6.PNG
--------------------------------------------------------------------------------
/Image-7.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piinalpin/flask-crud/a016109745c8b144c46a3e6d6eb25ebbccfdb270/Image-7.PNG
--------------------------------------------------------------------------------
/Image-8.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piinalpin/flask-crud/a016109745c8b144c46a3e6d6eb25ebbccfdb270/Image-8.PNG
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | run: flask db init && flask db migrate && flask db upgrade
2 | web: gunicorn run:app
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CRUD Application With Flask and SQLAlchemy (Python 3)
2 |
3 | Tutorial for building Create, Read, Update and Delete Website Application With Flask and SQLAlchemy
4 |
5 | ## Getting Started
6 |
7 | These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system.
8 |
9 | ### Prerequisites
10 |
11 | Make sure you have installed Python 3 on your device
12 |
13 | ### Project structure
14 | ```
15 | * flask-project/
16 | |--- app/
17 | | |--- module/
18 | | | |--- __init__.py
19 | | | |--- controller.py
20 | | | |--- models.py
21 | | |--- templates/ (html file)
22 | | |--- __init__.py
23 | |--- venv/
24 | |--- run.py
25 | ```
26 |
27 | ### Step to create flask crud
28 |
29 | A step by step series of examples that tell you how to get a development env running
30 |
31 | 1. Install virtual environment
32 | ```
33 | pip install virtualenv
34 | ```
35 | 2. Create virtual environment and activate inside your flask-crud directory according the above structure
36 | ```
37 | virtualenv venv
38 | > On windows -> venv\Scripts\activate
39 | > On linux -> . env/bin/activate
40 | ```
41 | 3. Install some third party librares on your virtual environment with pip
42 | ```
43 | pip install flask sqlalchemy flask-sqlalchemy
44 | ```
45 | 4. Create `run.py` directory inside flask-project according the above structure
46 | ```python
47 | from app import app
48 | app.run(debug=True, host='127.0.0.1', port=5000)
49 | ```
50 | 5. Create `controller.py` according the abpove structure `flask-crud/app/module/`
51 | ```python
52 | from flask import render_template, request
53 | from app import app
54 |
55 | @app.route('/')
56 | def index():
57 | return "My CRUD Flask App"
58 | ```
59 | 6. Create `__init__.py` inside app directory according the above structure `flask-crud/app/`
60 | ```python
61 | from flask import Flask
62 |
63 | app = Flask(__name__)
64 |
65 | from app.module.controller import *
66 | ```
67 | 7. Run first this application to make sure can running with terminal or command promt
68 | ```
69 | python run.py
70 | ```
71 | 9. Access `localhost:5000` according port that created in `run.py`
72 |
73 | 
74 |
75 | 10. Create an input form called `home.html` inside `templates` directory according the above structure
76 | ```html
77 |
78 |
79 |
80 |
81 | Flask Crud
82 |
83 |
84 | Form Add Mahasiswa
85 |
102 |
103 |
104 | ```
105 | 11. Change `return "My CRUD Flask App"` in `controller.py` to `return render_template("home.html")`
106 | ```python
107 | from flask import render_template, request
108 | from app import app
109 |
110 | @app.route('/')
111 | def index():
112 | return render_template("home.html")
113 | ```
114 |
115 | 
116 |
117 | 12. Then modify function `index()` to accept method `POST` request
118 | ```python
119 | @app.route('/', methods=['GET', 'POST'])
120 | def index():
121 | if request.method == 'POST':
122 | print(request.form)
123 | return render_template("home.html")
124 | ```
125 | 
126 | 
127 |
128 | 13. Configure the database with SQLAlchemy, you should modify `__init__.py` and it will be created `flaskcrud.db` inside `app` directory
129 | ```python
130 | import os
131 | from flask import Flask
132 |
133 | project_dir = os.path.dirname(os.path.abspath(__file__))
134 | database_file = "sqlite:///{}".format(os.path.join(project_dir, "flaskcrud.db"))
135 |
136 | app = Flask(__name__)
137 | app.config["SQLALCHEMY_DATABASE_URI"] = database_file
138 | app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
139 |
140 | from app.module.controller import *
141 | ```
142 | 14. Define model to application, you should create `models.py` file inside `module` directory according the above structure.
143 | ```python
144 | from flask_sqlalchemy import SQLAlchemy
145 | from app import app
146 |
147 | db = SQLAlchemy(app)
148 |
149 | class Mahasiswa(db.Model):
150 | id = db.Column(db.Integer, unique=True, primary_key=True, nullable=False)
151 | nim = db.Column(db.String, nullable=False)
152 | name = db.Column(db.String, nullable=False)
153 |
154 | def __repr__(self):
155 | return "".format(self.name)
156 | ```
157 |
158 | 15. The structure of database should like as follows
159 |
160 | Mahasiswa |
161 | ------------- |
162 | `id (Integer, PK, Autoincrement, NOT NULL)` |
163 | `name (String, NOT NULL)` |
164 | `nim (String, NOT NULL)` |
165 |
166 | 16. Stop app if that is still running, press `CTRL+C` key to quit and type `python` to go to python terminal
167 |
168 | 
169 |
170 | 17. Type command bellow to create database file `flaskcrud.db`
171 | ```
172 | >>> from app.module.models import db
173 | >>> db.create_all()
174 | >>> exit()
175 | ```
176 | 18. The structure project will be look as follows
177 | ```
178 | * flask-project/
179 | |--- app/
180 | | |--- module/
181 | | | |--- __init__.py
182 | | | |--- controller.py
183 | | | |--- models.py
184 | | |--- templates/ (html file)
185 | | |--- __init__.py
186 | | |--- flaskcrud.db
187 | |--- venv/
188 | |--- run.py
189 | ```
190 | 19. Import database from `models.py` add this line `from .models import db, Mahasiswa` to the `controller.py`, it's mean import from `models.py` for `db` variable and class `Mahasiswa`
191 | 20. Modify `controller.py` to create function to storing data of `Mahasiswa` then save to the database that is already made and retrieving data with `Mahasiswa.query.all()` it will be retrieving all data from database then made with `try` and `except` to handling an error
192 | ```python
193 | @app.route('/', methods=['GET','POST'])
194 | def index():
195 | if request.method == 'POST':
196 | name = request.form['name']
197 | nim = request.form['nim']
198 | try:
199 | mhs = Mahasiswa(nim=nim, name=name)
200 | db.session.add(mhs)
201 | db.session.commit()
202 | except Exception as e:
203 | print("Failed to add data.")
204 | print(e)
205 | listMhs = Mahasiswa.query.all()
206 | print(listMhs)
207 | return render_template("home.html", data=enumerate(listMhs,1))
208 | ```
209 | 21. The statement of `data=enumerate(listMhs,1)` mean data will show from 1 and so on, not from the id
210 |
211 | 22. Then modify `home.html` file to show that data is already inputed on database from input form
212 | ```html
213 |
214 |
215 |
216 |
217 | Flask Crud
218 |
219 |
220 | Form Add Mahasiswa
221 |
238 |
239 | Data Mahasiswa
240 |
241 |
242 | No |
243 | Nomor Induk Mahasiswa |
244 | Nama |
245 |
246 | {% for no, x in data %}
247 |
248 | {{ no }} |
249 | {{ x.nim }} |
250 | {{ x.name }} |
251 |
252 | {% endfor %}
253 |
254 |
255 |
256 | ```
257 | 
258 |
259 | 23. Then modify `home.html` to add action button that will __UPDATE__ and __DELETE__ data from database using id from collection. On `href="form-update/{{ x.id }}"` it will be route to `/form-update/1` to GET parameters.
260 | ```html
261 |
262 |
263 |
264 |
265 | Flask Crud
266 |
267 |
268 | Form Add Mahasiswa
269 |
286 |
287 | Data Mahasiswa
288 |
289 |
290 | No |
291 | Nomor Induk Mahasiswa |
292 | Nama |
293 | Action |
294 |
295 | {% for no, x in data %}
296 |
297 | {{ no }} |
298 | {{ x.nim }} |
299 | {{ x.name }} |
300 | Edit | Delete |
301 |
302 | {% endfor %}
303 |
304 |
305 |
306 | ```
307 | 
308 |
309 | 24. Then create `form-update.html` for the input form on update
310 | ```html
311 |
312 |
313 |
314 |
315 | Flask Crud
316 |
317 |
318 | Form Update Mahasiswa
319 |
337 |
338 |
339 | ```
340 | 
341 |
342 | 25. Then create function to __UPDATE__ data from the collections in `controller.py`, on __UPDATE__ you should create two function to load or render form input and update to database from method __POST__ on form input using `Mahasiswa.query.filter_by(id=id).first()` to find data filter by id and `db.session.commit()` to save the data
343 | ```python
344 | @app.route('/form-update/')
345 | def updateForm(id):
346 | mhs = Mahasiswa.query.filter_by(id=id).first()
347 | return render_template("form-update.html", data=mhs)
348 |
349 | @app.route('/form-update', methods=['POST'])
350 | def update():
351 | if request.method == 'POST':
352 | id = request.form['id']
353 | name = request.form['name']
354 | nim = request.form['nim']
355 | try:
356 | mhs = Mahasiswa.query.filter_by(id=id).first()
357 | mhs.name = name
358 | mhs.nim = nim
359 | db.session.commit()
360 | except Exception as e:
361 | print("Failed to update data")
362 | print(e)
363 | return redirect("/")
364 | ```
365 | 26. And modify import flask on top line change to `from flask import render_template, request, redirect`
366 |
367 | 27. Then create the __DELETE__ function to delete data from the collections in `controller.py` using filter by id and `db.session.delete(mhs)` function
368 | ```python
369 | @app.route('/delete/')
370 | def delete(id):
371 | try:
372 | mhs = Mahasiswa.query.filter_by(id=id).first()
373 | db.session.delete(mhs)
374 | db.session.commit()
375 | except Exception as e:
376 | print("Failed delete mahasiswa")
377 | print(e)
378 | return redirect("/")
379 | ```
380 |
381 | ### After change structure of flask project
382 | ```
383 | * flask-project/
384 | |--- app/
385 | | |--- module/
386 | | | |--- __init__.py
387 | | | |--- controller.py
388 | | | |--- models.py
389 | | |--- templates/
390 | | | |--- form-update.html
391 | | | |--- home.html
392 | | |--- __init__.py
393 | | |--- flaskcrud.db
394 | |--- venv/
395 | |--- run.py
396 | ```
397 |
398 | ## Built With
399 |
400 | * [Python 3](https://www.python.org/download/releases/3.0/) - The language programming used
401 | * [Flask](http://flask.pocoo.org/) - The web framework used
402 | * [Virtualenv](https://virtualenv.pypa.io/en/latest/) - The virtual environment used
403 | * [SQL Alchemy](https://www.sqlalchemy.org/) - The database library
404 | * [Flask-SQLAlchemy](http://flask-sqlalchemy.pocoo.org/2.3/) - Flask and SQL Alchemy connector
405 |
406 | ## Want to demo online?
407 | #### [Flask Crud With SQL Alchemy Built in Python 3](https://flask-crud-sample.herokuapp.com)
408 |
409 | ## Clone or Download
410 |
411 | You can clone or download this project
412 | ```
413 | > Clone : git clone https://github.com/piinalpin/flask-crud.git
414 | ```
415 |
416 | ## Authors
417 |
418 | * **Alvinditya Saputra** - *Initial work* - [DSS Consulting](https://dssconsulting.id/) - [LinkedIn](https://linkedin.com/in/piinalpin) [Instagram](https://www.instagram.com/piinalpin) [Twitter](https://www.twitter.com/piinalpin)
419 |
--------------------------------------------------------------------------------
/app/__init__.py:
--------------------------------------------------------------------------------
1 | import os
2 | from flask import Flask
3 |
4 | project_dir = os.path.dirname(os.path.abspath(__file__))
5 | database_file = "sqlite:///{}".format(os.path.join(project_dir, "flaskcrud.db"))
6 |
7 | app = Flask(__name__)
8 | app.config["SQLALCHEMY_DATABASE_URI"] = database_file
9 | app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
10 |
11 | from app.module.controller import *
--------------------------------------------------------------------------------
/app/flaskcrud.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piinalpin/flask-crud/a016109745c8b144c46a3e6d6eb25ebbccfdb270/app/flaskcrud.db
--------------------------------------------------------------------------------
/app/module/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piinalpin/flask-crud/a016109745c8b144c46a3e6d6eb25ebbccfdb270/app/module/__init__.py
--------------------------------------------------------------------------------
/app/module/controller.py:
--------------------------------------------------------------------------------
1 | from flask import render_template, request, redirect
2 | from app import app
3 | from .models import db, Mahasiswa
4 |
5 | @app.route('/', methods=['GET','POST'])
6 | def index():
7 | if request.method == 'POST':
8 | name = request.form['name']
9 | nim = request.form['nim']
10 | try:
11 | mhs = Mahasiswa(nim=nim, name=name)
12 | db.session.add(mhs)
13 | db.session.commit()
14 | except Exception as e:
15 | print("Failed to add data.")
16 | print(e)
17 | listMhs = Mahasiswa.query.all()
18 | print(listMhs)
19 | return render_template("home.html", data=enumerate(listMhs,1))
20 |
21 | @app.route('/form-update/')
22 | def updateForm(id):
23 | mhs = Mahasiswa.query.filter_by(id=id).first()
24 | return render_template("form-update.html", data=mhs)
25 |
26 | @app.route('/form-update', methods=['POST'])
27 | def update():
28 | if request.method == 'POST':
29 | id = request.form['id']
30 | name = request.form['name']
31 | nim = request.form['nim']
32 | try:
33 | mhs = Mahasiswa.query.filter_by(id=id).first()
34 | mhs.name = name
35 | mhs.nim = nim
36 | db.session.commit()
37 | except Exception as e:
38 | print("Failed to update data")
39 | print(e)
40 | return redirect("/")
41 |
42 | @app.route('/delete/')
43 | def delete(id):
44 | try:
45 | mhs = Mahasiswa.query.filter_by(id=id).first()
46 | db.session.delete(mhs)
47 | db.session.commit()
48 | except Exception as e:
49 | print("Failed delete mahasiswa")
50 | print(e)
51 | return redirect("/")
--------------------------------------------------------------------------------
/app/module/models.py:
--------------------------------------------------------------------------------
1 | from flask_sqlalchemy import SQLAlchemy
2 | from app import app
3 |
4 | db = SQLAlchemy(app)
5 |
6 | class Mahasiswa(db.Model):
7 | id = db.Column(db.Integer, unique=True, primary_key=True, nullable=False)
8 | nim = db.Column(db.String, nullable=False)
9 | name = db.Column(db.String, nullable=False)
10 |
11 | def __repr__(self):
12 | return "".format(self.name)
--------------------------------------------------------------------------------
/app/templates/form-update.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Flask Crud
6 |
7 |
8 | Form Update Mahasiswa
9 |
27 |
28 |
--------------------------------------------------------------------------------
/app/templates/home.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Flask Crud
6 |
7 |
8 | Form Add Mahasiswa
9 |
26 |
27 | Data Mahasiswa
28 |
29 |
30 | No |
31 | Nomor Induk Mahasiswa |
32 | Nama |
33 | Action |
34 |
35 | {% for no, x in data %}
36 |
37 | {{ no }} |
38 | {{ x.nim }} |
39 | {{ x.name }} |
40 | Edit | Delete |
41 |
42 | {% endfor %}
43 |
44 |
45 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Click==7.0
2 | Flask==1.0.2
3 | Flask-SQLAlchemy==2.3.2
4 | gunicorn==19.9.0
5 | itsdangerous==1.1.0
6 | Jinja2==2.10
7 | MarkupSafe==1.1.0
8 | numpy==1.15.4
9 | pandas==0.23.4
10 | python-dateutil==2.7.5
11 | pytz==2018.7
12 | six==1.12.0
13 | SQLAlchemy==1.2.15
14 | Werkzeug==0.14.1
15 |
--------------------------------------------------------------------------------
/run.py:
--------------------------------------------------------------------------------
1 | from app import app
2 | if __name__ == '__main__':
3 | app.run(host='localhost', port=8000, debug=True)
--------------------------------------------------------------------------------