Create Python Flask App in MVC Format
Flask is a microframework written in Python. It helps to create a small app to large scale web application.
Advantages of using flask framework are as follows:
Easy installation
Small size
Large community support
Fast in execution
In this article, we will create a simple blog to understand the structure and code pattern of flask framework.
Create a flask project
You may already installed python. If not installed please follow the link below.
https://www.python.org/downloads/
Install PIP that is a package installer in python.
curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
python get-pip.py
Install environment for flask app.
pip install Flask
pip install virtualenv
Now create your application directory on your desired location. In our example this is flaskblog.
Clone Flask MVC Structure from Github:
https://github.com/sheetalkumar105/flaskmvc.git
git clone https://github.com/sheetalkumar105/flaskmvc.git
You will get the file structure as follows:
Flaskblog L app L controller L __init__.py L HomeController.py L helpers L __init__.py L Utility.py
L models L __init__.py L AuthModel.py L routes L __init__.py L back.py L front.py L static L views L __init__.py
L app.py L config.py L setup.py |
Now start Flask App:
sudo pip install -e .
export FLASK_APP=app/__init__.py
export FLASK_DEBUG=1
flask run
You will get the following message:
* Serving Flask app "app"
* Forcing debug mode on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 114-170-438
Now open browser and open link: http://127.0.0.1:5000/
To change the database connection open app/config.py and configure
config['MONGO_DBNAME'] = 'flaskblog'
config['MONGO_URI'] = 'mongodb://localhost:27017/flaskblog'
Now create a post model to retrieve posts. Create a file PostModel.py in models directory.
Write the code inside that:
from ..app import mongo
from flask_pymongo import ObjectId
from app.helpers.Utility import toDictionaryArray
from datetime import datetime
class PostModel():
def __init__(self):
pass
def getPost(self,_id):
users = mongo.db.posts.find({'_id':ObjectId(_id)})
post=toDictionaryArray(users)
return post[0]
def getAllPosts(self):
users = mongo.db.posts.find()
return toDictionaryArray(users)
def addPost(self, title, content,image):
d = datetime.now()
insertdata = {'title': title, 'content': content, 'image': image, 'status': "1", 'created_at': d, 'updated_at': d}
res = mongo.db.posts.insert(insertdata)
return str(ObjectId(res))
def updatePost(self, _id,title, content,image):
d = datetime.now()
updatedata = {'title': title, 'content': content, 'image': image, 'status': "1", 'updated_at': d}
mongo.db.posts.update({'_id': ObjectId(_id)}, {'$set': updatedata}, False, True)
return _id
def deletePost(self, _id):
mongo.db.posts.delete_many({'_id': ObjectId(_id)})
postmodel=PostModel()
Add in helpers/Utility.py
def allowed_file(filename, ALLOWED_EXTENSIONS):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
Update Home Controller:
from flask import request,redirect
from flask import render_template
from app.models.AuthModel import authmodel
from app.models.PostModel import postmodel
from app.helpers.Utility import sendResponse,allowed_file
import os
import time
class HomeController():
def __init__(self):
pass
def index(self):
posts=postmodel.getAllPosts()
return render_template('index.html', title='Home', posts=posts)
def register(self):
return render_template('registration.html', title='Registration')
def new(self):
return render_template('createpost.html', title='New Post')
def registeruser(self):
_firstname = request.form.get('firstname', '')
_lastname = request.form.get('lastname', '')
_email = request.form.get('email', '')
_password = request.form.get('password', '')
return sendResponse(authmodel.registerUser(_firstname,_lastname,_email,_password))
def writePost(self):
title=request.form.get("title","")
content=request.form.get("content","")
image = request.files['image']
filename=''
if image and allowed_file(image.filename, set(['png', 'jpg', 'jpeg', 'gif'])):
ilename, file_extension = os.path.splitext(image.filename)
millis = int(round(time.time() * 1000))
filename = str(millis) + file_extension
image.save(os.path.join("app/static/images", filename))
_id=postmodel.addPost(title,content,filename)
return redirect("/")
homecontroller=HomeController()
Add in Front Router:
@front.route('/registration', methods=['POST'])
def registeruser():
return homecontroller.registeruser()
@front.route('/new', methods=['GET'])
def newpost():
return homecontroller.new()
@front.route('/new', methods=['POST'])
def writePost():
return homecontroller.writePost()
Now create views inside views directory that uses jinja Template Engine.
createpost.html
<html>
<head>
<title>{{ title }} - New Post</title>
</head>
<body>
<a href="/">Home</a> <form id="registration" method="post" enctype="multipart/form-data">
Title: <input type="text" name="title" /><br>
Content: <input type="text" name="content" /><br>
Image: <input type="file" name="image" /><br>
<button type="submit" id="btnSubmit">Submit</button>
</form>
</body>
</html>
index.html
<html>
<head>
<title>{{ title }} - Blog</title>
</head>
<body>
{% for post in posts: %}
<div>
<h4>{{post["title"]}}</h4>
<p>{{post["content"]}}</p>
</div>
{% endfor %}
</body>
</html>
All setup is done. Open link http://127.0.0.1:5000/new to create a new post.
All the post will view on http://127.0.0.1:5000/