Sunteți pe pagina 1din 42

MINI PROJECT REPORT

ONLINE BLOG
USING PYTHON’S FLASK
FRAMEWORK
Submitted by: Sameer Khan 1612914006
Ali Mehdi Zaidi 1612914001

Under Supervision of: Prof. Saroj Kumari

FORTE INSTITUTE OF TECHNOLOGY,MEERUT

June,2018
CERTIFICATE

Certified that the report on “ONLINE BLOG


USING PYTHON’S FLASK FRAMEWORK”
is bonafide record of the mini-project work
submitted by
SAMEER KHAN 1612914006
ALI MEHDI ZAIDI 1612914001
in their 4th semester of Master of Computer
Applications during the year 2017-18,
carried out the project work under my
supervision.

Prof. Saroj Kumari HOD, Fit college , Meerut


ACKNOWLEDGEMENT

We are pleased to acknowledge Prof. Saroj Kumari for their invaluable guidance during
the course of this project work

We extend our sincere thanks to Prof. Nitin who continuously helped us throughout the
project and without his guidance, this project would have been an uphill task.

JUNE, 2018 Sameer Khan


1612914006

Ali Mehdi Zaidi

1612914001
CONTENTS

CERTIFICATE

ACKNOWLEDGEMENTS

CONTENTS

INTRODUCTION

TOOLS REQUIRED

INTRODUCTION TO FLASK AND ITS FEATURES

PROJECT STRUCTURE

PROJECT FILES

SQL QUERIES

SCREENSHOTS

CONCLUSION

REFERENCES
INTRODUCTION

This report discusses the implementation of the python’s flask framework


for creating an online blog. Online blog are essential tools in the world of
the internet today. They help to create an online database for all the essential
articles a person has to use anywhere and anytime by having an access to the
internet on a machine.

The choice for python as a programming language is


relevant to the current applications of it in 2018. Not only it is easy ,simple
and human readable, it is also powerful enough to find its application in all
areas of software development.

Flask is a micro framework that is easy to


implement and gives control to the developer to implement all its features.

The uses on the blog will be able to:

1. Read the articles on the blog online.

2. Create an account and login.

3. Write their articles in their account.

4. Update the articles in their account.

5. Delete the articles in the account.


TOOLS REQUIRED:

HARDWARE:
CPU: INTEL CORE I3
RAM: 4 GB

SOFTWARE:
PYTHON VERSION 3
FLASK VERSION 0.12.2
BOOTSTRAP VERSION 4
MYSQL

EXTENSIONS TO FLASK FRAMEWORK:


pip install flask-mysqldb
pip install flask-wtf
pip install passlib
An introduction to Flask and its features
The Flask framework sticks together the amazing Werkzeug and Jinja2
frameworks, responsible for answering requests and presenting the output
(HTML, maybe). In the MVC architecture, also known as Model-View-
Controller, Flask covers C and V. Flask does not provide you with an integrated
model layer out-of-the-box as that is not actually needed for a web application.
If we do need to work with a database, just pick your database solution from the
many available and create your own model layer. Features of the framework:
A development server and debugger (sanity-friendly)
Unicode support (Latin language-friendly)
WSGI compliance (uWsgi-friendly)
A unit-test client client (code with quality)
URL routing (it brings tears to my eyes, it's so beautiful!)
Request dispatching
Secure cookies
Sessions
Jinja2 templates (tags, filters, macros, and more)

With that much, you can handle Ajax requests, browser requests, and user
sessions between requests; route HTTP requests to your controllers; evaluate
form data; respond to HTML and JSON; and so on.

Flask was born in 2010

Flask is a minimalistic web framework based on Jinja2 and Werkzeug

Flask does not enforce a specific project architecture.

Flask does not come with bundled functionality in terms of database integration,
a forms library, administration interface, or migration tools. You can have these
through extensions.
PROJECT STRUCTURE
flaskapp
|--static
| |--css
| |--style.css
|--templates
| |--includes
|-- _formhelpers.html
|-- _messages.html
|-- _navbar.html
| |--add_articles.html
| |--about.html
| |--article.html
| |--articles.html
| |--dashboard.html
| |--index.html
| |--layout.html
| |--edit_articles.html
| |--login.html
| |--register.html
|--main.py
|--data.py
Main.py
# do not change starts

from flask import Flask,


render_template,flash,redirect,url_for,session,logging,request
#from data import Articles
from flask_mysqldb import MySQL
from wtforms import Form, StringField,
TextAreaField,PasswordField,validators
from passlib.hash import sha256_crypt
from functools import wraps
app = Flask(__name__)
#configure MySql
app.config['MYSQL_HOST']='127.0.0.1'
app.config['MYSQL_USER']='root'
app.config['MYSQL_PASSWORD']='admin'
app.config['MYSQL_DB']='myflaskapp'
app.config['MYSQL_CURSORCLASS']='DictCursor'
#init mysql
mysql = MySQL(app)
#Articles = Articles()
# do not change ends

# server/
@app.route('/')
def index():
return render_template('index.html')
# server/order
@app.route('/about')
def about():
return render_template('about.html')

#articles
@app.route('/articles')
def articles():
# create cursor
cur = mysql.connection.cursor()

# get articles
result = cur.execute('SELECT * FROM articles')
articles = cur.fetchall()
if result > 0:
return render_template('articles.html', articles=articles)
else:
msg = 'No Article Found'
return render_template('articles.html', msg=msg)
# cursor close
cur.close()

#single article
@app.route('/article/<string:id>/')
def article(id):
# create cursor
cur = mysql.connection.cursor()

# get articles
result = cur.execute('SELECT * FROM articles WHERE id=%s',[id])
article = cur.fetchone()
return render_template('article.html',article=article)

#register form class


class RegisterForm(Form):
name = StringField('Name',[validators.Length(min=1,max=50)])
username=StringField('Username',[validators.Length(min=4,max=25)])
email=StringField('Email',[validators.Length(min=6,max=50)])
password = PasswordField('Password',[
validators.DataRequired(),
validators.EqualTo('confirm',message='Password does not match')
])
confirm = PasswordField('Confirm Password')

@app.route('/register',methods=['GET','POST'])
def register():
form = RegisterForm(request.form)
if request.method == 'POST' and form.validate():
name=form.name.data
email=form.email.data
username=form.username.data
password = sha256_crypt.encrypt(str(form.password.data))

#create cursor
cur=mysql.connection.cursor()
#execute cursor
cur.execute("INSERT INTO users(name,email,username,password)
VALUES(%s,%s,%s,%s)",(name,email,username,password))

#commit to db
mysql.connection.commit()

#close connection
cur.close()
flash('You are now registered and can log in','success')

redirect(url_for('index'))

return render_template('register.html',form=form)

#user login
@app.route('/login',methods=['GET','POST'])
def login():
if request.method == 'POST':
#get form fields
username = request.form['username']
password_candidate = request.form['password']

#create cursor
cur= mysql.connection.cursor()

#get user by username


result = cur.execute("SELECT * FROM users WHERE username=
%s",[username])

if result > 0 :
#get stored hash
data = cur.fetchone()
password = data['password']

#compare passwords
if sha256_crypt.verify(password_candidate,password):
#Passed
session['logged_in']= True
session['username']= username

flash('You are now logged in','success')


return redirect(url_for('dashboard'))
else:
error = 'Invalid Login'
return render_template('login.html', error=error)
#close connection
cur.close()
else:
error='Username not found'
return render_template('login.html',error=error)

return render_template('login.html')

def is_logged_in(f):
@wraps(f)
def wrap(*args,**kwargs):
if 'logged_in' in session:
return f(*args,**kwargs)
else:
flash('Unauthorised, Please login','danger')
return redirect(url_for('login'))
return wrap

@app.route('/dashboard')
@is_logged_in
def dashboard():
#create cursor
cur = mysql.connection.cursor()

#get articles
result = cur.execute('SELECT * FROM articles')
articles = cur.fetchall()
if result>0:
return render_template('dashboard.html',articles=articles)
else:
msg='No Article Found'
return render_template('dashboard.html',msg=msg)
#cursor close
cur.close()

#article form class


class ArticleForm(Form):
title =StringField('Title',[validators.length(min=1,max=200)])
body= TextAreaField('Body',[validators.length(min=30)])
#add article
@app.route('/add_article',methods=['GET','POST'])
@is_logged_in
def add_article():
form=ArticleForm(request.form)
if request.method == 'POST' and form.validate():
title= form.title.data
body=form.body.data

#create cursor
cur= mysql.connection.cursor()
#execute
cur.execute("INSERT INTO articles(title,body,author)
VALUES(%s,%s,%s)",(title,body,session['username']))

#commit to db
mysql.connection.commit()

#close connection
cur.close()

flash("Article Created",'success')

return redirect(url_for('dashboard'))

return render_template('add_articles.html',form=form)

#edit article
@app.route('/edit_article/<string:id>',methods=['GET','POST'])
@is_logged_in
def edit_article(id):
#create cursor
cur = mysql.connection.cursor()

#get article by id
result= cur.execute("SELECT * FROM articles WHERE id = %s",[id])
article = cur.fetchone()
#get form
form = ArticleForm(request.form)
#populate article form fields
form.title.data = article['title']
form.body.data= article['body']
if request.method == 'POST' and form.validate():
title= request.form['title']
body= request.form['body']

#create cursor
cur= mysql.connection.cursor()
#execute
cur.execute("UPDATE articles SET title=%s, body=%s WHERE
id=%s",(title, body,id))

#commit to db
mysql.connection.commit()

#close connection
cur.close()

flash("Article Updated",'success')

return redirect(url_for('dashboard'))

return render_template('edit_article.html',form=form)

@app.route('/logout')
@is_logged_in
def logout():
session.clear()
flash('You are now logged out','success')
return redirect(url_for('login'))

#delete article
@app.route('/delete_article/<string:id>',methods=['POST'])
@is_logged_in
def delete_article(id):
#create cursor
cur= mysql.connection.cursor()

#execute
cur.execute("DELETE FROM articles WHERE id= %s",[id])
#commit to db
cur.connection.commit()

#close connection
cur.close()

flash('Article Deleted','success')

return redirect(url_for('dashboard'))

# Launching the server


if __name__ == "__main__":
app.secret_key='secret123'
app.run(debug=True)
Data.py
def Articles():
articles= [
{
'id':1,
'title':'Article One',
'body':'lorem ipsumlorem ipsumlorem ipsumlorem ipsumlorem
ipsumlorem ipsumlorem ipsumlorem ipsum',
'author':'Brad Traversy',
'create_date':'04-05-2018'
},
{
'id': 2,
'title': 'Article Two',
'body': 'lorem ipsumlorem ipsumlorem ipsumlorem ipsumlorem
ipsumlorem ipsumlorem ipsumlorem ipsum',
'author': 'John Doe',
'create_date': '04-05-2018'
},
{
'id': 3,
'title': 'Article Three',
'body': 'lorem ipsumlorem ipsumlorem ipsumlorem ipsumlorem
ipsumlorem ipsumlorem ipsumlorem ipsum',
'author': 'Brad Traversy',
'create_date': '04-05-2018'
}
]

return articles
Layout.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.
css">
<title>MyFlaskApp</title>
<script
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.j
s"></script>
</head>
<body>
<!-- Header -->
<div class="header-wrap d-none d-md-block">
<div class="container">
<div class="row">

<!-- Left header box -->


<header class="col-6 text-left">
<h1>MyFlaskApp</h1>
</header>

<!-- Right header box -->


<div class="col-6 text-right">

</div>
</div>
</div>
</div>

<!-- Main navigation -->


<nav class="navbar navbar-expand-md navbar-dark bg-primary">
<div class="container">

<!-- Company name shown on mobile -->


<a class="navbar-brand d-md-none d-lg-none d-xl-none"
href="#"><span>Company</span>Name</a>
<!-- Mobile menu toggle -->
<button class="navbar-toggler" type="button" data-
toggle="collapse" data-target="#mainNavbar" aria-
controls="mainNavbar" aria-expanded="false" aria-label="Toggle
navigation">
<span class="navbar-toggler-icon"></span>
</button>

<!-- Main navigation items -->


<div class="collapse navbar-collapse" id="mainNavbar">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="/">Home <span class="sr-
only">(current)</span></a>
</li>

<li class="nav-item">
<a class="nav-link" href="/articles">Articles</a>
</li>

<li class="nav-item">
<a class="nav-link" href="/about">About</a>
</li>

{% if session.logged_in %}
<li class="nav-item"><a class="nav-link"
href="/dashboard">Dashboard</a></li>
<li class="nav-item"><a class="nav-link"
href="/logout">Logout</a></li>
{% else %}
<li class="nav-item"><a class="nav-link"
href="/register">Register</a></li>
<li class="nav-item"><a class="nav-link"
href="/login">Login</a></li>
{% endif %}
</ul>
</div>
</div>
</nav>
<div class="container">

{% include 'includes/_messages.html' %}
{% block body %}
{% endblock %}
</div>
<script src="//cdn.ckeditor.com/4.9.2/standard/ckeditor.js"></script>
<script type="text/javascript">
CKEDITOR.replace('editor')
</script>
</body>
</html>
Index.html
{% extends 'layout.html' %}

{% block body %}
<div class="jumbotron text-center">
<h1>Welcome to the Flask App</h1>
<p class="lead">This is the app made
from the flask framework for python.</p>

{% if session.logged_in == NULL %}
<a href="/register" class="btn btn-primary
btn-lg">Register</a>
<a href="/login" class="btn btn-success
btn-lg">Login</a>
{% endif %}
</div>
{% endblock %}
Login.html
{% extends 'layout.html' %}

{% block body %}
<br/>
<h1>Login</h1>

<form action ="" method ="POST">


<div class = 'form-group'>
<label>Username</label>
<input type="text" name="username" classname="form-
control" value={{ request.form.username}}>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" name="password" classname =
"form-control" value={{ request.form.password }}>
</div>
<button type = "submit" class=" btn btn-
primary">Submit</button>
</form>
{% endblock %}
Register.html
{% extends 'layout.html' %}

{% block body %}
<br/>
<h1>Register</h1>
{% from "includes/_formhelpers.html" import render_field %}
<form method="post" action="">
<div class="form-group">
{{render_field(form.name,class_="form-control")}}
</div>
<div class="form-group">
{{render_field(form.email,class_="form-control")}}
</div>
<div class="form-group">
{{render_field(form.username,class_="form-control")}}
</div>
<div class="form-group">
{{render_field(form.password,class_="form-control")}}
</div>
<div class="form-group">
{{render_field(form.confirm,class_="form-control")}}
</div>
<p><input type="submit" class="btn btn-primary"
value="Submit"></p>
</form>
{% endblock %}
Edit_articles.html
{% extends 'layout.html' %}

{% block body %}
<br/>
<h1>Edit Article</h1>
{% from "includes/_formhelpers.html" import render_field %}
<form method="POST" action="">
<div class="form-group">
{{render_field(form.title,class_="form-control")}}
</div>
<div class="form-group">
{{render_field(form.body,class_="form-control",id='editor')}}
</div>
<p><input type="submit" class="btn btn-primary"
value="Submit"></p>
</form>
{% endblock %}
Dashboard.html
{% extends 'layout.html' %}

{% block body %}
<h1>Dashboard <small>Welcome {{session.username}} </small></h1>
<a class="btn btn-success" href="/add_article">Add Article</a>
<hr>
<table class="table table-striped">
<tr>
<th>
ID
</th>
<th>
Title
</th>
<th>
Author
</th>
<th>
Date
</th>
<th></th>
<th></th>
</tr>
{% for article in articles %}
<tr>
<td>{{ article.id}}</td>
<td>{{ article.title }}</td>
<td>{{ article.author }}</td>
<td>{{ article.create_date }}</td>
<td><a href="edit_article/{{ article.id }}" class="btn btn-default
pull-right">Edit</a></td>
<td>
<form action="{{url_for('delete_article',id=article.id)}}"
method='post'>
<input type="hidden" name="_method" value="DELETE">
<input type="submit" value="Delete" class="btn btn-
danger">
</form>
</td>
</tr>
{% endfor %}
</table>

{% endblock %}
Articles.html
{% extends 'layout.html' %}

{% block body %}
<br/>
<h1>Articles</h1>
<ul class="list-group">
{% for article in articles %}
<li class="list-group-item"><a href="article/{{ article.id }}">{{
article.title }}</a></li>
{% endfor %}
</ul>
{% endblock %}
Article.html
{% extends 'layout.html' %}

{% block body%}
<h1>{{article.title}}</h1>
<small>Written by {{ article.author }} on {{ article.create_date }}</small>
<hr>
<div>
{{ article.body | safe }}
</div>
{% endblock %}

Add_articles.html

{% extends 'layout.html' %}

{% block body %}
<br/>
<h1>Add Article</h1>
{% from "includes/_formhelpers.html" import render_field %}
<form method="post" action="">
<div class="form-group">
{{render_field(form.title,class_="form-control")}}
</div>
<div class="form-group">
{{render_field(form.body,class_="form-control",id='editor')}}
</div>
<p><input type="submit" class="btn btn-primary"
value="Submit"></p>
</form>
{% endblock %}
Add_article.html
{% extends 'layout.html' %}

{% block body %}
<br/>
<h1>Add Article</h1>
{% from "includes/_formhelpers.html" import render_field %}
<form method="post" action="">
<div class="form-group">
{{render_field(form.title,class_="form-control")}}
</div>
<div class="form-group">
{{render_field(form.body,class_="form-control",id='editor')}}
</div>
<p><input type="submit" class="btn btn-primary"
value="Submit"></p>
</form>
{% endblock %}
About.html
{% extends 'layout.html' %}

{% block body %}
<div class="jumbotron">
<h1>About us</h1>
<p class="lead">Samtechnologies &#x00AE corporation aims at building
quality web applications
for everyone to use. We aim to make it simple , clean and reliable for our
users.
If you wish to have your own web app feel free to contact us. <br/><br/>
Samtechnologies Corporation<br/>
American Tower,<br/>
Walker St.<br/>
New York, NW51SA<br/>
USA
</p>
</div>

{% endblock %}
_navbar.html
<!-- Header -->
<div class="header-wrap d-none d-md-block">
<div class="container">
<div class="row">

<!-- Left header box -->


<header class="col-6 text-left">
<h1>MyFlaskApp</h1>
</header>

<!-- Right header box -->


<div class="col-6 text-right">

</div>
</div>
</div>
</div>

<!-- Main navigation -->


<nav class="navbar navbar-expand-md navbar-dark bg-primary">
<div class="container">

<!-- Company name shown on mobile -->


<a class="navbar-brand d-md-none d-lg-none d-xl-none"
href="#"><span>Company</span>Name</a>

<!-- Mobile menu toggle -->


<button class="navbar-toggler" type="button" data-
toggle="collapse" data-target="#mainNavbar" aria-
controls="mainNavbar" aria-expanded="false" aria-label="Toggle
navigation">
<span class="navbar-toggler-icon"></span>
</button>

<!-- Main navigation items -->


<div class="collapse navbar-collapse" id="mainNavbar">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="/">Home <span class="sr-
only">(current)</span></a>
</li>

<li class="nav-item">
<a class="nav-link" href="/articles">Articles</a>
</li>

<li class="nav-item">
<a class="nav-link" href="/about">About</a>
</li>

<li class="nav-item"><a class="nav-link"


href="/register">Register</a></li>

</ul>

</div>

</div>
</nav>
_messages.html
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}

{% for category, message in messages %}


<div class="alert alert-{{ category }}">{{ message }}</div>
{% endfor %}

{% endif %}
{% endwith %}

{% if error %}
<div class="alert alert-danger">{{ error }}</div>
{% endif %}

{% if error %}
<div class="alert alert-success">{{ msg }}</div>
{% endif %}
_formhelpers.html
{% macro render_field(field) %}
{{ field.label }}
{{ field(**kwargs)|safe }}
{% if field.errors %}
{% for error in field.errors %}
<span class="help-inline">{{ errors }}</span>
{% endfor %}
{% endif %}
{% endmacro %}
SQL QUERIES:
1. CREATE TABLE users( id INT (11) AUTO_INCREMENT PRIMARY
KEY,name VARCHAR(100),email VARCHAR(100),username
VARCHAR(100),password VARCHAR(100),register_date
TIMESTAMP DEFAULT CURRENT_TIMESTAMP);

2. CREATE TABLE articles (id INT(11) AUTO_INCREMENT PRIMARY


KEY,title VARCHAR(255),author VARCHAR(100),body
TEXT,create_date TIMESTAMP DEFAULT
CURRENT_TIMESTAMP);
SCREENSHOTS:
SCREENSHOTS
CONCLUSION
After building the web application, we are able to learn about the
functioning of the flask framework and the power of python programming
language. We have seen how the MODEL VIEW CONTROLLER (MVC)
works in the application and helps to modularize the various parts of the
application.
Flask does not come with bundled functionality in terms of
database integration, a forms library, administration interface, or
migration tools. You can have these through extensions, but they are all
external to Flask. If you need these extensions right at the beginning of
your project and you don't want to set it up (or can't spare the time to), you
might do better with a full-fledged MVC all-in one, low-cohesive, and high-
coupling framework such as Django.
References:
Building Web Applications with Flask by Italo Maia

Beginning Python 3.0 by Magnus Lie Hetland

S-ar putea să vă placă și