Database Table
CREATE 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
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
#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
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.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('/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:
            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) VALUES (%s,%s,%s,%s)",(_title,_description,blog_user_id,now,))
                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 = 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']}
            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/userHome.htmlBinding retrieved data to html via JQuery templates
url for uquery templates https://github.com/BorisMoore/jquery-tmpl
http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.js
bind data inside the ul with class list-group
//templates/userHome.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Flask Add Edit Delete with Jquery ajax, 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) {
                // Parse the received JSON string
                var data = JSON.parse(res);
                //Populate the Pop up
                $('#editTitle').val(data[0]['Title']);
                $('#editDescription').val(data[0]['Description']);
                 
                // Trigger the Pop Up
                $('#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">
        <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>
      <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>
              </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>
templates/error.html
//templates/error.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Unauthorized Access</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>
</head>
<body>
    <div class="container">
        <div class="header">
            <nav>
                <ul class="nav nav-pills pull-right">
                    <li role="presentation" class="active"><a href="/">Home</a></li>
                    <li role="presentation"><a href="/login">Sign In</a></li>
                    <li role="presentation"><a href="/signUp">Sign Up</a></li>
                </ul>
            </nav>
            <img src="/static/images/Flask_Icon.png" alt="Flask_Icon.png"/ > 
        </div>
      <div class="jumbotron">
        <h1>{{error}}</h1>        
      </div>
        <footer class="footer">
            <p>©tutorial101.blogspot.com</p>
        </footer>
    </div>
</body>
</html>
templates/addBlog.html
//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>
</head>
<body>
    <div class="container">
        <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 class="form-horizontal" method="post" action="/addBlog">
<fieldset>
<legend>Create Your Blog</legend>
		{% if error %}
		  <div class="alert alert-danger">{{error}}</div>
		{% endif %}
<div class="form-group">
  <label class="col-md-4 control-label" for="txtTitle">Title</label>  
  <div class="col-md-4">
  <input id="txtTitle" name="inputTitle" type="text" placeholder="placeholder" class="form-control input-md">
  </div>
</div>
<div class="form-group">
  <label class="col-md-4 control-label" for="txtPost">Post</label>
  <div class="col-md-4">                     
    <textarea class="form-control" id="txtPost" name="inputDescription" ></textarea>
  </div>
</div>
<div class="form-group">
  <label class="col-md-4 control-label" for="singlebutton"></label>
  <div class="col-md-4">
    <input id="singlebutton" name="singlebutton" class="btn btn-primary" type="submit" value="Publish" />
  </div>
</div>
</fieldset>
</form>
</section>
        <footer class="footer">
            <p>©tutorial101.blogspot.com</p>
        </footer>
    </div>
  </body>
</html>

 
 
 
 
 
 
 
 
 
 
