Python Flask
https://flask.palletsprojects.com/en/2.3.x/installation/
Create an environment
C:\flask_dev>py -3 -m venv venv
Activate the environment
C:\flask_dev>venv\Scripts\activate
Install Flask
venv C:\flask_dev>pip install Flask
C:\flask_dev\myapp\app.py
Install requirements
Flask-SQLAlchemy
Flask-SQLAlchemy is an extension for Flask that adds support for SQLAlchemy to your application.
https://flask-sqlalchemy.palletsprojects.com/en/3.0.x/
(venv) PS C:\flask_dev\myapp>pip install -U Flask-SQLAlchemy
Flask-Bcrypt
Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application.
https://pypi.org/project/Flask-Bcrypt/
(venv) PS C:\flask_dev\myapp>pip install Flask-Bcrypt
C:\flask_dev\myapp\app.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | #C:\flask_dev\myapp\app.py from flask import Flask, render_template, request, redirect, url_for, session from werkzeug.utils import secure_filename import os from models import db, Users, Books app = Flask(__name__) app.config[ 'SECRET_KEY' ] = 'cairocoders-ednalan' #app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///flaskdb.db' # Databse configuration mysql Username:password@hostname/databasename SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_ECHO = True bcrypt = Bcrypt(app) db.init_app(app) with app.app_context(): db.create_all() app.config[ 'UPLOAD_FOLDER' ] = 'static/images' ALLOWED_EXTENSIONS = set ([ 'png' , 'jpg' , 'jpeg' , 'gif' ]) def allowed_file(filename): return '.' in filename and filename.rsplit( '.' , 1 )[ 1 ].lower() in ALLOWED_EXTENSIONS @app .route( '/register' , methods = [ 'GET' , 'POST' ]) def register(): mesage = '' if request.method = = 'POST' and 'name' in request.form and 'password' in request.form and 'email' in request.form : fullname = request.form[ 'name' ] password = request.form[ 'password' ] email = request.form[ 'email' ] user_exists = Users.query.filter_by(email = email).first() is not None if user_exists: mesage = 'Email already exists !' elif not re.match(r '[^@]+@[^@]+\.[^@]+' , email): mesage = 'Invalid email address !' elif not fullname or not password or not email: mesage = 'Please fill out the form !' else : hashed_password = bcrypt.generate_password_hash(password) new_user = Users(name = fullname, email = email, password = hashed_password) db.session.add(new_user) db.session.commit() mesage = 'You have successfully registered !' elif request.method = = 'POST' : mesage = 'Please fill out the form !' return render_template( 'register.html' , mesage = mesage) @app .route( '/login' , methods = [ 'GET' , 'POST' ]) def login(): mesage = '' if request.method = = 'POST' : email = request.form[ 'email' ] password = request.form[ 'password' ] #print(email) #print(password) if email = = ' ' or password == ' ': mesage = 'Please enter email and password !' else : user = Users.query.filter_by(email = email).first() print (user) if user is None : mesage = 'Please enter correct email / password !' else : if not bcrypt.check_password_hash(user.password, password): mesage = 'Please enter correct email and password !' else : session[ 'loggedin' ] = True session[ 'userid' ] = user. id session[ 'name' ] = user.name session[ 'email' ] = user.email mesage = 'Logged in successfully !' return redirect(url_for( 'dashboard' )) return render_template( 'login.html' , mesage = mesage) @app .route( "/dashboard" , methods = [ 'GET' , 'POST' ]) def dashboard(): if 'loggedin' in session: return render_template( "dashboard.html" ) return redirect(url_for( 'login' )) @app .route( '/logout' ) def logout(): session.pop( 'loggedin' , None ) session.pop( 'userid' , None ) session.pop( 'email' , None ) return redirect(url_for( 'login' )) # Manage Books @app .route( "/books" , methods = [ 'GET' , 'POST' ]) def books(): if 'loggedin' in session: books = Books.query. all () return render_template( "books.html" , books = books) return redirect(url_for( 'login' )) @app .route( '/save_book' ,methods = [ 'POST' ]) def save_book(): msg = '' if 'loggedin' in session: if request.method = = 'POST' : name = request.form[ 'name' ] isbn = request.form[ 'isbn' ] action = request.form[ 'action' ] if action = = 'updateBook' : bookid = request.form[ 'bookid' ] book = Books.query.get(bookid) book.name = name book.isbn = isbn db.session.commit() print ( "UPDATE book" ) else : file = request.files[ 'uploadFile' ] filename = secure_filename( file .filename) print (filename) if file and allowed_file( file .filename): file .save(os.path.join(app.config[ 'UPLOAD_FOLDER' ], filename)) filenameimage = file .filename book = Books(name = name, picture = filenameimage, isbn = isbn) db.session.add(book) db.session.commit() print ( "INSERT INTO book" ) else : msg = 'Invalid Uplaod only png, jpg, jpeg, gif' return redirect(url_for( 'books' )) elif request.method = = 'POST' : msg = 'Please fill out the form !' return render_template( "books.html" , msg = msg) return redirect(url_for( 'login' )) @app .route( "/edit_book" , methods = [ 'GET' , 'POST' ]) def edit_book(): msg = '' if 'loggedin' in session: bookid = request.args.get( 'bookid' ) print (bookid) books = Books.query.get(bookid) return render_template( "edit_books.html" , books = books) return redirect(url_for( 'login' )) @app .route( "/delete_book" , methods = [ 'GET' ]) def delete_book(): if 'loggedin' in session: bookid = request.args.get( 'bookid' ) book = Books.query.get(bookid) print (book.picture) db.session.delete(book) db.session.commit() os.unlink(os.path.join(app.config[ 'UPLOAD_FOLDER' ], book.picture)) return redirect(url_for( 'books' )) return redirect(url_for( 'login' )) if __name__ = = '__main__' : app.run(debug = True ) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #C:\flask_dev\myapp\models.py from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() class Users(db.Model): __tablename__ = "user" id = db.Column(db.Integer, primary_key = True ) name = db.Column(db.String( 150 ), index = True , unique = True ) email = db.Column(db.String( 150 ), index = True , unique = True ) password = db.Column(db.String( 255 ), index = True , unique = True ) class Books(db.Model): __tablename__ = "tblbook" bookid = db.Column(db.Integer, primary_key = True ) name = db.Column(db.String( 150 ), index = True , unique = True ) picture = db.Column(db.String( 150 ), index = True , unique = True ) isbn = db.Column(db.String( 255 ), index = True , unique = True ) |
https://github.com/ColorlibHQ/AdminLTE/releases
templates/register.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | // <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "utf-8" > <meta name= "viewport" content= "width=device-width, initial-scale=1" > <title>AdminLTE 3 | Registration Page</title> <!-- Google Font: Source Sans Pro --> <link rel= "stylesheet" href= "https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback" > <!-- Font Awesome --> <link rel= "stylesheet" href= "{{ url_for('static',filename='plugins/fontawesome-free/css/all.min.css') }}" > <!-- icheck bootstrap --> <link rel= "stylesheet" href= "{{ url_for('static',filename='plugins/icheck-bootstrap/icheck-bootstrap.min.css') }}" > <!-- Theme style --> <link rel= "stylesheet" href= "{{ url_for('static',filename='css/adminlte.min.css') }}" > </head> <body class = "hold-transition register-page" > <div class = "register-box" > <div class = "register-logo" > <a href= "../../index2.html" ><b>Admin</b>LTE</a> </div> <div class = "card" > <div class = "card-body register-card-body" > <p class = "login-box-msg" >Register a new membership</p> <form action= "{{ url_for('register') }}" method= "post" > {% if mesage is defined and mesage %} <div class = "alert alert-warning" >{{ mesage }}</div> {% endif %} <div class = "input-group mb-3" > <input type= "text" class = "form-control" id= "name" name= "name" placeholder= "Full name" > <div class = "input-group-append" > <div class = "input-group-text" > <span class = "fas fa-user" ></span> </div> </div> </div> <div class = "input-group mb-3" > <input type= "email" class = "form-control" id= "email" name= "email" placeholder= "Email" > <div class = "input-group-append" > <div class = "input-group-text" > <span class = "fas fa-envelope" ></span> </div> </div> </div> <div class = "input-group mb-3" > <input type= "password" class = "form-control" id= "password" name= "password" placeholder= "Password" > <div class = "input-group-append" > <div class = "input-group-text" > <span class = "fas fa-lock" ></span> </div> </div> </div> <div class = "row" > <div class = "col-8" > <div class = "icheck-primary" > <input type= "checkbox" id= "agreeTerms" name= "terms" value= "agree" > <label for = "agreeTerms" > I agree to the <a href= "#" >terms</a> </label> </div> </div> <!-- /.col --> <div class = "col-4" > <button type= "submit" class = "btn btn-primary btn-block" >Register</button> </div> <!-- /.col --> </div> </form> <div class = "social-auth-links text-center" > <p>- OR -</p> <a href= "#" class = "btn btn-block btn-primary" > <i class = "fab fa-facebook mr-2" ></i> Sign up using Facebook </a> <a href= "#" class = "btn btn-block btn-danger" > <i class = "fab fa-google-plus mr-2" ></i> Sign up using Google+ </a> </div> <a href= "{{url_for('login')}}" class = "text-center" >I already have an account</a> </div> <!-- /.form-box --> </div><!-- /.card --> </div> <!-- /.register-box --> <!-- jQuery --> <script src= "{{ url_for('static',filename='plugins/jquery/jquery.min.js') }}" ></script> <!-- Bootstrap 4 --> <script src= "{{ url_for('static',filename='plugins/bootstrap/js/bootstrap.bundle.min.js') }}" ></script> <!-- AdminLTE App --> <script src= "{{ url_for('static',filename='js/adminlte.min.js') }}" ></script> </body> </html> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | //templates/login.html <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "utf-8" > <meta name= "viewport" content= "width=device-width, initial-scale=1" > <title>AdminLTE 3 | Log in</title> <!-- Google Font: Source Sans Pro --> <link rel= "stylesheet" href= "https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback" > <!-- Font Awesome --> <link rel= "stylesheet" href= "{{ url_for('static',filename='plugins/fontawesome-free/css/all.min.css') }}" > <!-- icheck bootstrap --> <link rel= "stylesheet" href= "{{ url_for('static',filename='plugins/icheck-bootstrap/icheck-bootstrap.min.css') }}" > <!-- Theme style --> <link rel= "stylesheet" href= "{{ url_for('static',filename='css/adminlte.min.css') }}" > </head> <body class = "hold-transition login-page" > <div class = "login-box" > <div class = "login-logo" > <a href= "../../index2.html" ><b>Admin</b>LTE</a> </div> <!-- /.login-logo --> <div class = "card" > <div class = "card-body login-card-body" > <p class = "login-box-msg" >Sign in to start your session</p> <form action= "{{ url_for('login') }}" method= "post" > {% if mesage is defined and mesage %} <div class = "alert alert-warning" >{{ mesage }}</div> {% endif %} <div class = "input-group mb-3" > <input type= "email" class = "form-control" id= "email" name= "email" placeholder= "Email" > <div class = "input-group-append" > <div class = "input-group-text" > <span class = "fas fa-envelope" ></span> </div> </div> </div> <div class = "input-group mb-3" > <input type= "password" class = "form-control" id= "password" name= "password" placeholder= "Password" > <div class = "input-group-append" > <div class = "input-group-text" > <span class = "fas fa-lock" ></span> </div> </div> </div> <div class = "row" > <div class = "col-8" > <div class = "icheck-primary" > <input type= "checkbox" id= "remember" > <label for = "remember" > Remember Me </label> </div> </div> <!-- /.col --> <div class = "col-4" > <button type= "submit" class = "btn btn-primary btn-block" >Sign In</button> </div> <!-- /.col --> </div> </form> <div class = "social-auth-links text-center mb-3" > <p>- OR -</p> <a href= "#" class = "btn btn-block btn-primary" > <i class = "fab fa-facebook mr-2" ></i> Sign in using Facebook </a> <a href= "#" class = "btn btn-block btn-danger" > <i class = "fab fa-google-plus mr-2" ></i> Sign in using Google+ </a> </div> <!-- /.social-auth-links --> <p class = "mb-1" > <a href= "forgot-password.html" >I forgot my password</a> </p> <p class = "mb-0" > <a href= "{{url_for('register')}}" class = "text-center" >Register a new account</a> </p> </div> <!-- /.login-card-body --> </div> </div> <!-- /.login-box --> <!-- jQuery --> <script src= "{{ url_for('static',filename='plugins/jquery/jquery.min.js') }}" ></script> <!-- Bootstrap 4 --> <script src= "{{ url_for('static',filename='plugins/bootstrap/js/bootstrap.bundle.min.js') }}" ></script> <!-- AdminLTE App --> <script src= "{{ url_for('static',filename='js/adminlte.min.js') }}" ></script> </body> </html> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | //templates/dashboard.html {% extends 'layout.html' %} {% block body %} <!-- Content Header (Page header) --> <div class = "content-header" > <div class = "container-fluid" > <div class = "row mb-2" > <div class = "col-sm-6" > <h1 class = "m-0" >Dashboard</h1> </div><!-- /.col --> <div class = "col-sm-6" > <ol class = "breadcrumb float-sm-right" > <li class = "breadcrumb-item" ><a href= "#" >Home</a></li> <li class = "breadcrumb-item active" >Dashboard v1</li> </ol> </div><!-- /.col --> </div><!-- /.row --> </div><!-- /.container-fluid --> </div> <!-- /.content-header --> <!-- Main content --> <section class = "content" > <div class = "container-fluid" > <!-- Small boxes (Stat box) --> <div class = "row" > <div class = "col-lg-3 col-6" > <!-- small box --> <div class = "small-box bg-info" > <div class = "inner" > <h3>150</h3> <p>Total Books</p> </div> <div class = "icon" > <i class = "ion ion-bag" ></i> </div> <a href= "#" class = "small-box-footer" >More info <i class = "fas fa-arrow-circle-right" ></i></a> </div> </div> <!-- ./col --> <div class = "col-lg-3 col-6" > <!-- small box --> <div class = "small-box bg-success" > <div class = "inner" > <h3>53<sup style= "font-size: 20px" >%</sup></h3> <p>Available Books</p> </div> <div class = "icon" > <i class = "ion ion-stats-bars" ></i> </div> <a href= "#" class = "small-box-footer" >More info <i class = "fas fa-arrow-circle-right" ></i></a> </div> </div> <!-- ./col --> <div class = "col-lg-3 col-6" > <!-- small box --> <div class = "small-box bg-warning" > <div class = "inner" > <h3>44</h3> <p>Returned Books</p> </div> <div class = "icon" > <i class = "ion ion-person-add" ></i> </div> <a href= "#" class = "small-box-footer" >More info <i class = "fas fa-arrow-circle-right" ></i></a> </div> </div> <!-- ./col --> <div class = "col-lg-3 col-6" > <!-- small box --> <div class = "small-box bg-danger" > <div class = "inner" > <h3>65</h3> <p>Issued Books</p> </div> <div class = "icon" > <i class = "ion ion-pie-graph" ></i> </div> <a href= "#" class = "small-box-footer" >More info <i class = "fas fa-arrow-circle-right" ></i></a> </div> </div> <!-- ./col --> </div> <!-- /.row --> <!-- /.row (main row) --> </div><!-- /.container-fluid --> </section> <!-- /.content --> {% endblock %} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | //templates/layout.html <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "utf-8" > <meta name= "viewport" content= "width=device-width, initial-scale=1" > <title>AdminLTE 3 | Dashboard</title> <!-- Google Font: Source Sans Pro --> <link rel= "stylesheet" href= "https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback" > <!-- Font Awesome --> <link rel= "stylesheet" href= "{{ url_for('static',filename='plugins/fontawesome-free/css/all.min.css') }}" > <!-- Ionicons --> <!-- iCheck --> <link rel= "stylesheet" href= "{{ url_for('static',filename='plugins/icheck-bootstrap/icheck-bootstrap.min.css') }}" > <!-- Theme style --> <link rel= "stylesheet" href= "{{ url_for('static',filename='css/adminlte.min.css') }}" > </head> <body class = "hold-transition sidebar-mini layout-fixed" > <div class = "wrapper" > <!-- Preloader --> <div class = "preloader flex-column justify-content-center align-items-center" > <img class = "animation__shake" src= "{{ url_for('static',filename='img/AdminLTELogo.png') }}" alt= "AdminLTELogo" height= "60" width= "60" > </div> <!-- Navbar --> <nav class = "main-header navbar navbar-expand navbar-white navbar-light" > <!-- Left navbar links --> <ul class = "navbar-nav" > <li class = "nav-item" > <a class = "nav-link" data-widget= "pushmenu" href= "#" role= "button" ><i class = "fas fa-bars" ></i></a> </li> <li class = "nav-item d-none d-sm-inline-block" > <a href= "index3.html" class = "nav-link" >Home</a> </li> <li class = "nav-item d-none d-sm-inline-block" > <a href= "#" class = "nav-link" >Contact</a> </li> </ul> <!-- Right navbar links --> <ul class = "navbar-nav ml-auto" > <!-- Navbar Search --> <li class = "nav-item" > <a class = "nav-link" data-widget= "navbar-search" href= "#" role= "button" > <i class = "fas fa-search" ></i> </a> <div class = "navbar-search-block" > <form class = "form-inline" > <div class = "input-group input-group-sm" > <input class = "form-control form-control-navbar" type= "search" placeholder= "Search" aria-label= "Search" > <div class = "input-group-append" > <button class = "btn btn-navbar" type= "submit" > <i class = "fas fa-search" ></i> </button> <button class = "btn btn-navbar" type= "button" data-widget= "navbar-search" > <i class = "fas fa-times" ></i> </button> </div> </div> </form> </div> </li> <li class = "nav-item" > <a class = "nav-link" data-widget= "control-sidebar" data-controlsidebar-slide= "true" href= "#" role= "button" > <i class = "fas fa-th-large" ></i> </a> </li> </ul> </nav> <!-- /.navbar --> <!-- Main Sidebar Container --> <aside class = "main-sidebar sidebar-dark-primary elevation-4" > <!-- Brand Logo --> <a href= "index3.html" class = "brand-link" > <img src= "{{ url_for('static',filename='img/AdminLTELogo.png') }}" alt= "AdminLTE Logo" class = "brand-image img-circle elevation-3" style= "opacity: .8" > <span class = "brand-text font-weight-light" >AdminLTE 3</span> </a> <!-- Sidebar --> <div class = "sidebar" > <!-- Sidebar user panel (optional) --> <div class = "user-panel mt-3 pb-3 mb-3 d-flex" > <div class = "image" > <img src= "{{ url_for('static',filename='img/avatar4.png') }}" class = "img-circle elevation-2" alt= "User Image" > </div> <div class = "info" > <a href= "#" class = "d-block" >{{session.name}}</a> </div> </div> <!-- SidebarSearch Form --> <div class = "form-inline" > <div class = "input-group" data-widget= "sidebar-search" > <input class = "form-control form-control-sidebar" type= "search" placeholder= "Search" aria-label= "Search" > <div class = "input-group-append" > <button class = "btn btn-sidebar" > <i class = "fas fa-search fa-fw" ></i> </button> </div> </div> </div> <!-- Sidebar Menu --> <nav class = "mt-2" > <ul class = "nav nav-pills nav-sidebar flex-column" data-widget= "treeview" role= "menu" data-accordion= "false" > <!-- Add icons to the links using the .nav-icon class with font-awesome or any other icon font library --> <li class = "nav-item menu-open" > <a href= "{{ url_for('dashboard') }}" class = "nav-link active" > <i class = "nav-icon fas fa-tachometer-alt" ></i> <p> Dashboard <i class = "right fas fa-angle-left" ></i> </p> </a> </li> <li class = "nav-item" > <a href= "{{ url_for('books') }}" class = "nav-link" > <i class = "nav-icon fas fa-table" ></i> <p> Manage Books </p> </a> </li> <li class = "nav-item" > <a href= "{{ url_for('logout') }}" class = "nav-link" > <i class = "nav-icon fas fa-th" ></i> <p> Logout </p> </a> </li> </ul> </nav> <!-- /.sidebar-menu --> </div> <!-- /.sidebar --> </aside> <!-- Content Wrapper. Contains page content --> <div class = "content-wrapper" > {% block body %}{% endblock %} </div> <!-- /.content-wrapper --> <footer class = "main-footer" > All rights reserved. <div class = "float-right d-none d-sm-inline-block" > <b>Version</b> 3.2.0 </div> </footer> <!-- Control Sidebar --> <aside class = "control-sidebar control-sidebar-dark" > <!-- Control sidebar content goes here --> </aside> <!-- /.control-sidebar --> </div> <!-- ./wrapper --> <!-- jQuery --> <script src= "{{ url_for('static',filename='plugins/jquery/jquery.min.js') }}" ></script> <!-- Bootstrap 4 --> <script src= "{{ url_for('static',filename='plugins/bootstrap/js/bootstrap.bundle.min.js') }}" ></script> <!-- AdminLTE App --> <script src= "{{ url_for('static',filename='js/adminlte.min.js') }}" ></script> <script> $(document).ready( function (){ $( '#addBook' ).click( function (){ $( '#bookModal' ).modal({ backdrop: 'static' , keyboard: false }); $( "#bookModal" ).on( "shown.bs.modal" , function () { $( '#bookForm' )[0].reset(); $( '.modal-title' ).html( "<i class='fa fa-plus'></i> Add book" ); $( '#action' ).val( 'addBook' ); $( '#save' ).val( 'Save' ); }); }); }); </script> </body> </html> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | //templates/books.html {% extends 'layout.html' %} {% block body %} <!-- Content Header (Page header) --> <div class = "content-header" > <div class = "container-fluid" > <div class = "row mb-2" > <div class = "col-sm-6" > <h1 class = "m-0" >Manage Books</h1> </div><!-- /.col --> <div class = "col-sm-6" > <ol class = "breadcrumb float-sm-right" > <li class = "breadcrumb-item" ><a href= "#" >Home</a></li> <li class = "breadcrumb-item active" >Manage Books</li> </ol> </div><!-- /.col --> </div><!-- /.row --> </div><!-- /.container-fluid --> </div> <!-- /.content-header --> <!-- Main content --> <section class = "content" > <div class = "container-fluid" > <div class = "row" > <h3>Book Listing</h3> <br> <div class = "float-right mb-2 col-md-2" > <button type= "button" id= "addBook" class = "btn btn-info" title= "Add book" ><span class = "glyphicon glyphicon-plus" >Add Book</span></button> </div> <br><br> <table class = "table table-striped" > <thead> <tr> <th></th> <th>Book</th> <th>ISBN</th> <th></th> <th></th> </tr> </thead> <tbody> {% for book in books %} <tr> <td> {% if book.picture %} <img src= "../static/images/{{book.picture}}" width= "80" height= "90" > {% else %} <img src= "../static/images/default.jpg" width= "80" height= "90" > {% endif %} </td> <td>{{book.name}}</td> <td>{{book.isbn}}</td> <td><a href= "{{url_for('edit_book', bookid=book.bookid)}}" class = "btn btn-primary" >Edit</a></td> <td><a href= "{{url_for('delete_book', bookid=book.bookid)}}" class = "btn btn-danger" > Delete </a></td> </tr> {% endfor %} </tbody> </table> </div> </div><!-- /.container-fluid --> </section> <!-- /.content --> <div class = "modal fade" id= "bookModal" > <div class = "modal-dialog" > <form method= "post" id= "bookForm" action= "{{ url_for('save_book')}}" enctype= "multipart/form-data" > <div class = "modal-content" > <div class = "modal-header" > <h4 class = "modal-title" >Add New</h4> <button type= "button" class = "close" data-dismiss= "modal" aria-label= "Close" > <span aria-hidden= "true" >×</span> </button> </div> <div class = "modal-body" > <div class = "form-group" > <label for = "book" class = "control-label" >Book</label> <input type= "text" name= "name" id= "name" autocomplete= "off" class = "form-control" placeholder= "book name" /> </div> <div class = "form-group" > <label for = "book" class = "control-label" >ISBN No</label> <input type= "text" name= "isbn" id= "isbn" autocomplete= "off" class = "form-control" placeholder= "isbn name" /> </div> <div class = "form-group" > <label>File Upload</label> <input type= "file" name= "uploadFile" accept= ".jpg, .png" /> </div> </div> <div class = "modal-footer justify-content-between" > <button type= "button" class = "btn btn-default" data-dismiss= "modal" >Close</button> <input type= "hidden" name= "action" id= "action" value= "" /> <input type= "submit" name= "save" id= "save" class = "btn btn-primary" value= "Save changes" /> </div> </div> </form> <!-- /.modal-content --> </div> <!-- /.modal-dialog --> </div> {% endblock %} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | //templates/books.html {% extends 'layout.html' %} {% block body %} <!-- Content Header (Page header) --> <div class = "content-header" > <div class = "container-fluid" > <div class = "row mb-2" > <div class = "col-sm-6" > <h1 class = "m-0" >Manage Books</h1> </div><!-- /.col --> <div class = "col-sm-6" > <ol class = "breadcrumb float-sm-right" > <li class = "breadcrumb-item" ><a href= "#" >Home</a></li> <li class = "breadcrumb-item active" >Manage Books</li> </ol> </div><!-- /.col --> </div><!-- /.row --> </div><!-- /.container-fluid --> </div> <!-- /.content-header --> <!-- Main content --> <section class = "content" > <div class = "container-fluid" > <div class = "row" > <div class = "col-md-12" > <h3>Book Edit</h3> <form method= "post" id= "bookForm" action= "{{ url_for('save_book')}}" > <div class = "card-body" > <div class = "form-group" > <label for = "book" class = "control-label" >Book</label> <input type= "text" name= "name" id= "name" autocomplete= "off" class = "form-control" placeholder= "book name" value= "{{books.name}}" /> </div> <div class = "form-group" > <label for = "book" class = "control-label" >ISBN No</label> <input type= "text" name= "isbn" id= "isbn" autocomplete= "off" class = "form-control" placeholder= "isbn name" value= "{{books.isbn}}" /> </div> <div class = "form-group" > <label for = "book" class = "control-label" >Picture</label> <img src= "static/images/{{books.picture}}" width= "360" /> </div> <input type= "hidden" name= "bookid" id= "bookid" value= "{{books.bookid}}" /> <input type= "hidden" name= "action" id= "action" value= "updateBook" /> <input type= "submit" name= "save" id= "save" class = "btn btn-info" value= "Save" /> </div> </form> </div> </div> </div><!-- /.container-fluid --> </section> {% endblock %} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | //templates/edit_books.html {% extends 'layout.html' %} {% block body %} <!-- Content Header (Page header) --> <div class = "content-header" > <div class = "container-fluid" > <div class = "row mb-2" > <div class = "col-sm-6" > <h1 class = "m-0" >Manage Books</h1> </div><!-- /.col --> <div class = "col-sm-6" > <ol class = "breadcrumb float-sm-right" > <li class = "breadcrumb-item" ><a href= "#" >Home</a></li> <li class = "breadcrumb-item active" >Manage Books</li> </ol> </div><!-- /.col --> </div><!-- /.row --> </div><!-- /.container-fluid --> </div> <!-- /.content-header --> <!-- Main content --> <section class = "content" > <div class = "container-fluid" > <div class = "row" > <div class = "col-md-12" > <h3>Book Edit</h3> <form method= "post" id= "bookForm" action= "{{ url_for('save_book')}}" > <div class = "card-body" > <div class = "form-group" > <label for = "book" class = "control-label" >Book</label> <input type= "text" name= "name" id= "name" autocomplete= "off" class = "form-control" placeholder= "book name" value= "{{books.name}}" /> </div> <div class = "form-group" > <label for = "book" class = "control-label" >ISBN No</label> <input type= "text" name= "isbn" id= "isbn" autocomplete= "off" class = "form-control" placeholder= "isbn name" value= "{{books.isbn}}" /> </div> <div class = "form-group" > <label for = "book" class = "control-label" >Picture</label> <img src= "static/images/{{books.picture}}" width= "360" /> </div> <input type= "hidden" name= "bookid" id= "bookid" value= "{{books.bookid}}" /> <input type= "hidden" name= "action" id= "action" value= "updateBook" /> <input type= "submit" name= "save" id= "save" class = "btn btn-info" value= "Save" /> </div> </form> </div> </div> </div><!-- /.container-fluid --> </section> {% endblock %} |