Flask Jquery ajax upload image with blueimp jQuery-File-Upload, jQuery Templates and MySQLdb Database
Database TableCREATE TABLE `tbl_blog` (
`blog_id` int(11) NOT NULL,
`blog_title` varchar(200) NOT NULL,
`blog_description` text NOT NULL,
`blog_user_id` int(11) NOT NULL,
`blog_date` datetime NOT NULL,
`blog_file_path` varchar(200) NOT NULL,
`blog_accomplished` int(11) NOT NULL,
`blog_private` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
app.py
#app.py
from flask import Flask, render_template, json, request, redirect, session, jsonify
from flask_mysqldb import MySQL,MySQLdb #pip install flask-mysqldb https://github.com/alexferl/flask-mysqldb
from datetime import datetime
import os
import uuid
app = Flask(__name__)
app.secret_key = "caircocoders-ednalan-2020"
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_USER'] = 'root'
app.config['MYSQL_PASSWORD'] = ''
app.config['MYSQL_DB'] = 'flaskdb'
app.config['MYSQL_CURSORCLASS'] = 'DictCursor'
mysql = MySQL(app)
app.config['UPLOAD_FOLDER'] = 'static/Uploads' #templates/static/Uploads/
@app.route('/')
def main():
return redirect('/userHome')
@app.route('/userHome')
def userHome():
session['sessionusername'] = "cairocoders@gmail.com"
print(session.get('sessionusername'))
if session.get('sessionusername'):
return render_template('userHome.html')
else:
return render_template('error.html',error = 'Unauthorized Access')
@app.route('/upload', methods=['GET', 'POST'])
def upload():
if request.method == 'POST':
file = request.files['file']
extension = os.path.splitext(file.filename)[1]
f_name = str(uuid.uuid4()) + extension
file.save(os.path.join(app.config['UPLOAD_FOLDER'], f_name))
return json.dumps({'filename':f_name})
@app.route('/addBlog', methods=['GET', 'POST'])
def addBlog():
now = datetime.now()
print("now =", now)
if request.method == 'POST':
_title = request.form['inputTitle']
_description = request.form['inputDescription']
_user = session.get('sessionusername')
# validate the received values
if _title and _description:
if request.form.get('filePath') is None:
_filePath = ''
else:
_filePath = request.form.get('filePath')
if request.form.get('private') is None:
_private = 0
else:
_private = 1
if request.form.get('done') is None:
_done = 0
else:
_done = 1
cur = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
result = cur.execute("SELECT * FROM users WHERE email = %s", [_user])
print(result)
if result > 0:
data = cur.fetchone()
blog_user_id = data['id']
cur.execute("INSERT INTO tbl_blog (blog_title, blog_description, blog_user_id, blog_date, blog_file_path, blog_accomplished, blog_private) VALUES (%s,%s,%s,%s,%s,%s,%s)",(_title,_description,blog_user_id,now,_filePath,_private,_done,))
mysql.connection.commit()
cur.close()
return redirect('/userHome')
else:
error = 'Invalid login'
return render_template('addBlog.html', error=error)
else:
error = 'Enter the required fields'
return render_template('addBlog.html', error=error)
return render_template('addBlog.html')
@app.route('/getBlog')
def getBlog():
if session.get('sessionusername'):
_user = '12'
cur = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
result = cur.execute("SELECT * FROM tbl_blog WHERE blog_user_id = %s", [_user])
blogs = cur.fetchall()
blogs_dict = []
for blog in blogs:
blog_dict = {
'Id': blog['blog_id'],
'Title': blog['blog_title'],
'Description': blog['blog_description'],
'Date': blog['blog_date']}
blogs_dict.append(blog_dict)
return json.dumps(blogs_dict)
else:
print("error getblog")
return render_template('error.html', error = 'Unauthorized Access')
@app.route('/getBlogById',methods=['GET', 'POST'])
def getBlogById():
if session.get('sessionusername'):
_id = request.form['id']
cur = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
result = cur.execute("SELECT * FROM tbl_blog WHERE blog_id = %s", [_id])
blogs = cur.fetchall()
blogs_dict = []
for blog in blogs:
blog_dict = {
'Id': blog['blog_id'],
'Title': blog['blog_title'],
'Description': blog['blog_description'],
'FilePath': blog['blog_file_path'],
'Done': blog['blog_accomplished'],
'Private': blog['blog_private']}
blogs_dict.append(blog_dict)
return json.dumps(blogs_dict)
else:
return render_template('error.html', error = 'Unauthorized Access')
@app.route('/updateBlog', methods=['POST'])
def updateBlog():
if session.get('sessionusername'):
_title = request.form['title']
_description = request.form['description']
_blog_id = request.form['id']
cur = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
cur.execute("""
UPDATE tbl_blog
SET blog_title = %s,
blog_description = %s
WHERE blog_id = %s
""", (_title, _description, _blog_id))
mysql.connection.commit()
cur.close()
return json.dumps({'status':'OK'})
else:
return render_template('error.html', error = 'Unauthorized Access')
@app.route('/deleteBlog',methods=['POST'])
def deleteBlog():
if session.get('sessionusername'):
_id = request.form['id']
_user = session.get('user')
cur = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
cur.execute('DELETE FROM tbl_blog WHERE blog_id = {0}'.format(_id))
mysql.connection.commit()
cur.close()
return json.dumps({'status':'OK'})
else:
return render_template('error.html', error = 'Unauthorized Access')
if __name__ == '__main__':
app.run(debug=True)
templates/addBlog.html
File upload via blueimp jQuery-File-Upload
https://github.com/blueimp/jQuery-File-Upload
Extract the source and add the following script references to addBlog.html
src="/static/js/jquery.fileupload.js
src="/static/js/jquery.fileupload-process.js
src="/static/js/jquery.fileupload-ui.js
//templates/addBlog.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Add Blog</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="/static/js/jquery.ui.widget.js"></script>
<script type="text/javascript" src="/static/js/jquery.fileupload.js"></script>
<script type="text/javascript" src="/static/js/jquery.fileupload-process.js"></script>
<script type="text/javascript" src="/static/js/jquery.fileupload-ui.js"></script>
<script>
$(function(){
$('#fileupload').fileupload({
url: 'upload',
dataType: 'json',
add: function (e, data) {
data.submit();
},
success:function(response,status) {
console.log(response.filename);
var filePath = 'static/Uploads/' + response.filename;
$('#imgUpload').attr('src',filePath);
$('#filePath').val(filePath);
console.log('success');
},
error:function(error){
console.log(error);
}
});
})
</script>
<style>
.btn-file {
position: relative;
overflow: hidden;
}
.btn-file input[type=file] {
position: absolute;
top: 0;
right: 0;
min-width: 100%;
font-size: 100px;
text-align: right;
filter: alpha(opacity=0);
opacity: 0;
outline: none;
background: white;
cursor: inherit;
display: block;
}
</style>
</head>
<body>
<div class="container" style="padding:20px;">
<div class="header">
<nav>
<ul class="nav nav-pills pull-right">
<li role="presentation" class="active"><a href="/userHome">Dashboard</a></li>
<li role="presentation"><a href="/addBlog">Add Blog</a></li>
<li role="presentation"><a href="/logout">Log Out</a></li>
</ul>
</nav>
<img src="/static/images/Flask_Icon.png" alt="Flask_Icon.png"/ >
</div>
<section>
<form role="form" method="post" action="/addBlog">
<legend>Create Your Blog Post</legend>
<div class="form-group">
<label for="txtTitle">Title</label>
<input id="txtTitle" name="inputTitle" type="text" placeholder="placeholder" class="form-control input-md">
</div>
<div class="form-group">
<label for="txtPost">Description</label>
<textarea class="form-control" id="txtPost" name="inputDescription"></textarea>
</div>
<div class="form-group">
<label for="txtPost">Photos</label>
<div class="input-group">
<span class="input-group-btn">
<span class="btn btn-primary btn-file">
Browse… <input type="file" id="fileupload" name="file" multiple>
</span>
</span>
<div class="pull-right">
<img id="imgUpload" style="width: 140px; height: 140px;" class="img-thumbnail"><input type="hidden" name="filePath" id="filePath"></input>
</div>
</div>
</div>
<div class="form-group">
<label>Mark this as private and not visible to others.</label>
<br/>
<input type="checkbox" name="private"> Mark as Private <span class="glyphicon glyphicon-lock" aria-hidden="true"></span>
</div>
<div class="form-group">
<label>Have you already accomplished this?</label>
<br/>
<input type="checkbox" name="done"> Mark as Done <span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
</div>
<div class="form-group">
<p class="text-center">
<input id="singlebutton" name="singlebutton" class="btn btn-primary" type="submit" value="Publish" />
</p>
</div>
</form>
</section>
<footer class="footer">
<p>©tutorial101.blogspot.com</p>
</footer>
</div>
</body>
</html>
templates/userHome.html
//templates/userHome.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Flask Jquery ajax upload image with blueimp jQuery-File-Upload, jQuery Templates and MySQLdb Database</title>
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.js"></script>
<script>
$(function(){
$('#btnUpdate').click(function(){
$.ajax({
url : '/updateBlog',
data : {title:$('#editTitle').val(),description:$('#editDescription').val(),id:localStorage.getItem('editId')},
type : 'POST',
success: function(res){
$('#editModal').modal('hide');
// Re populate the grid
GetBlogs();
},
error: function(error){
console.log(error);
}
});
});
});
function GetBlogs(){
$.ajax({
url : '/getBlog',
type : 'GET',
success: function(res){
var blogObj = JSON.parse(res);
$('#ulist').empty();
$('#listTemplate').tmpl(blogObj).appendTo('#ulist');
},
error: function(error){
console.log(error);
}
});
}
// get blog posts from db when the user signed in
$(function() {
$.ajax({
url: '/getBlog',
type: 'GET',
success: function(res) {
// Parse the JSON response
var blogObj = JSON.parse(res);
// Append to the template
$('#listTemplate').tmpl(blogObj).appendTo('#ulist');
},
error: function(error) {
console.log(error);
}
});
});
function Edit(elm) {
localStorage.setItem('editId',$(elm).attr('data-id'));
$.ajax({
url: '/getBlogById',
data: {
id: $(elm).attr('data-id')
},
type: 'POST',
success: function(res) {
var data = JSON.parse(res);
console.log(data);
$('#editTitle').val(data[0]['Title']);
$('#editDescription').val(data[0]['Description']);
$('#imgUpload').attr('src',data[0]['FilePath']);
if(data[0]['Private']=="1"){
$('#chkPrivate').attr('checked','checked');
}
if(data[0]['Done']=="1"){
$('#chkDone').attr('checked','checked');
}
$('#editModal').modal('show');
},
error: function(error) {
console.log(error);
}
});
}
function ConfirmDelete(elm){
localStorage.setItem('deleteId',$(elm).attr('data-id'));
$('#deleteModal').modal('show');
}
function Delete(){
$.ajax({
url : '/deleteBlog',
data : {id:localStorage.getItem('deleteId')},
type : 'POST',
success: function(res){
var result = JSON.parse(res);
if(result.status == 'OK'){
$('#deleteModal').modal('hide');
GetBlogs();
}
else{
alert(result.status);
}
},
error: function(error){
console.log(error);
}
});
}
</script>
<style>
.trash {
color: rgb(209, 91, 71);
}
.panel-body .checkbox {
display: inline-block;
margin: 0px;
}
.list-group {
margin-bottom: 0px;
}
</style>
</head>
<body>
<div class="container" style="padding:20px;">
<div class="header">
<nav>
<ul class="nav nav-pills pull-right">
<li role="presentation" class="active"><a href="/userHome">Dashboard</a></li>
<li role="presentation"><a href="/addBlog">Add Blog</a></li>
<li role="presentation"><a href="/logout">Log Out</a></li>
</ul>
</nav>
<img src="/static/images/Flask_Icon.png" alt="Flask_Icon.png"/ >
</div>
<p><h4>Flask Jquery ajax upload image with blueimp jQuery-File-Upload, jQuery Templates and MySQLdb Database</h4></p>
<script id="listTemplate" type="text/x-jQuery-tmpl">
<li class="list-group-item">
<div class="checkbox">
<label>
${Title}
</label>
</div>
<div class="pull-right action-buttons">
<a data-id=${Id} onclick="Edit(this)"><span class="glyphicon glyphicon-pencil"></span></a>
<a data-id=${Id} onclick="ConfirmDelete(this)"><span class="glyphicon glyphicon-trash"></span></a>
</div>
</li>
</script>
<div class="row">
<div class="col-md-12">
<div class="panel-body">
<ul id="ulist" class="list-group">
</ul>
</div>
</div>
</div>
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="editModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="editModalLabel">Update Blog</h4>
</div>
<div class="modal-body">
<form role="form">
<div class="form-group">
<label for="recipient-name" class="control-label">Title:</label>
<input type="text" class="form-control" id="editTitle">
</div>
<div class="form-group">
<label for="message-text" class="control-label">Description:</label>
<textarea class="form-control" id="editDescription"></textarea>
</div>
<div class="form-group">
<label for="txtPost">Photos</label>
<div class="input-group">
<span class="input-group-btn">
<span class="btn btn-primary btn-file">
Browse… <input type="file" id="fileupload" name="file" multiple>
</span>
</span>
<div class="pull-right">
<img id="imgUpload" style="width: 140px; height: 140px;" class="img-thumbnail"><input type="hidden" name="filePath" id="filePath"></input>
</div>
</div>
</div>
<div class="form-group">
<label>Mark this as private and not visible to others.</label><br/>
<input id="chkPrivate" name="private" type="checkbox"> Mark as Private <span class="glyphicon glyphicon-lock" aria-hidden="true"></span>
</div>
<div class="form-group">
<label>Have you already accomplished this?</label><br/>
<input id="chkDone" name="done" type="checkbox"> Mark as Done <span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button id="btnUpdate" type="button" class="btn btn-primary">Update</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header" style="text-align:center;">
<h4 class="modal-title" style="color:red;" id="deleteModalLabel">You are going to Delete this forever !!</h4>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" onclick="Delete()">Delete</button>
</div>
</div>
</div>
</div>
<footer class="footer">
<p>©tutorial101.blogspot.com</p>
</footer>
</div>
</body>
</html>