Search This Blog

2018/08/11

Flask SQLAlchemy CRUD Demo

To demonstrate Flask CRUD functionality we will use simple sqlite table having fields
name,city,addr,pin.Assuming name is primary key ,although we are not enforcing it in database design or code.

The class corresponding to our student table look like

class students(db.Model):
   id = db.Column('student_id', db.Integer, primary_key = True)
   name = db.Column(db.String(100))
   city = db.Column(db.String(50))
   addr = db.Column(db.String(200))
   pin = db.Column(db.String(10))

   def __init__(self, name, city, addr,pin):
      self.name = name
      self.city = city
      self.addr = addr
      self.pin = pin

complete app.py looks like below

from flask import Flask, request, flash, url_for, redirect, render_template
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///students.sqlite3'
app.config['SECRET_KEY'] = "random string"

db = SQLAlchemy(app)

class students(db.Model):
   id = db.Column('student_id', db.Integer, primary_key = True)
   name = db.Column(db.String(100))
   city = db.Column(db.String(50))
   addr = db.Column(db.String(200))
   pin = db.Column(db.String(10))

   def __init__(self, name, city, addr,pin):
      self.name = name
      self.city = city
      self.addr = addr
      self.pin = pin

@app.route('/')
def show_all():
   return render_template('show_all.html', students = students.query.all() )

@app.route('/delete')
def delete():
   sname = request.args.get('name')
   s = students.query.filter_by(name=sname).first()
   db.session.delete(s)
   db.session.commit()
   return redirect("/", code=302)

@app.route('/edit', methods = ['GET', 'POST'])
def edit():
      if request.method == 'POST':
            name = request.form['name']
            s = students.query.filter_by(name=name).first()
            s.city = request.form['city']
            s.addr = request.form['addr']
            s.pin = request.form['pin']
         
            db.session.commit()
            flash('Record was successfully added')
            return redirect(url_for('show_all'))
      else:
            sname = request.args.get('name')
            s = students.query.filter_by(name=sname).first()
            return render_template('edit.html',data = s)



@app.route('/new', methods = ['GET', 'POST'])
def new():
   if request.method == 'POST':
      if not request.form['name'] or not request.form['city'] or not request.form['addr']:
         flash('Please enter all the fields', 'error')
      else:
         student = students(request.form['name'], request.form['city'],request.form['addr'], request.form['pin'])
        
         db.session.add(student)
         db.session.commit()
         flash('Record was successfully added')
         return redirect(url_for('show_all'))

   s = students('','','','')
   return render_template('new.html',data=s)

if __name__ == '__main__':
   db.create_all()
   app.run(debug = True)

then we have template folder inside which we have 3 templates
edit.html,new.html & show_all.html.

show_all.html looks like below

<!DOCTYPE html>
<html lang = "en">
   <head></head>
   <body>
     
      <h3>
         <a href = "{{ url_for('show_all') }}">Comments - Flask
            SQLAlchemy example</a>
      </h3>
     
      <hr/>
      {%- for message in get_flashed_messages() %}
         {{ message }}
      {%- endfor %}
       
      <h3>Students (<a href = "{{ url_for('new') }}">Add Student
         </a>)</h3>
     
      <table border="1">
         <thead>
            <tr>
               <th>Name</th>
               <th>City</th>
               <th>Address</th>
               <th>Pin</th>
               <th></th>
               <th></th>
            </tr>
         </thead>
        
         <tbody>
            {% for student in students %}
               <tr>
                  <td>{{ student.name }}</td>
                  <td>{{ student.city }}</td>
                  <td>{{ student.addr }}</td>
                  <td>{{ student.pin }}</td>
                  <td>
                        <a href="/delete?name={{ student.name }}">delete</a>
                  </td>
                  <td>
                        <a href="/edit?name={{ student.name }}">edit</a>
                  </td>
               </tr>
            {% endfor %}
         </tbody>
      </table>
     
   </body>
</html>

it is simple html to display record in tabular format.

new.html template is html for adding new record

<!DOCTYPE html>
<html>
   <body>
  
      <h3>Students - Flask SQLAlchemy example</h3>
      <hr/>
     
      {%- for category, message in get_flashed_messages(with_categories = true) %}
         <div class = "alert alert-danger">
            {{ message }}
         </div>
      {%- endfor %}
     
      <form action = "{{ request.path }}" method = "post">
         <label for = "name">Name</label><br>
         <input type = "text" name = "name" placeholder = "Name" /><br>
         <label for = "email">City</label><br>
         <input type = "text" name = "city" placeholder = "city"  /><br>
         <label for = "addr">addr</label><br>
         <textarea name = "addr" placeholder = "addr"></textarea><br>
         <label for = "PIN">Pin</label><br>
         <input type = "text" name = "pin" placeholder = "pin" /><br>
         <input type = "submit" value = "Submit" />
      </form>
     
   </body>
</html>

edit.html is html template for editing existing record where name property is not editable.

<!DOCTYPE html>
<html>
   <body>
  
      <h3>Students - Flask SQLAlchemy example</h3>
      <hr/>
     
      {%- for category, message in get_flashed_messages(with_categories = true) %}
         <div class = "alert alert-danger">
            {{ message }}
         </div>
      {%- endfor %}
     
      <form action = "{{ request.path }}" method = "post">
         <label for = "name">Name</label><br>
         <input type = "text" name = "name" placeholder = "Name" readonly=true value="{{data.name}}" /><br>
         <label for = "email">City</label><br>
         <input type = "text" name = "city" placeholder = "city" value="{{data.city}}" /><br>
         <label for = "addr">addr</label><br>
         <textarea name = "addr" placeholder = "addr">{{data.addr}}</textarea><br>
         <label for = "PIN">Pin</label><br>
         <input type = "text" name = "pin" placeholder = "pin" value="{{data.pin}}" /><br>
         <input type = "submit" value = "Submit" />
      </form>
     
   </body>
</html>

For adding we need to create student object & add it to db & then commit

     student = students(request.form['name'], request.form['city'],request.form['addr'], request.form['pin'])
         db.session.add(student)
         db.session.commit()

For editing we have to first take clean object from database and then update its property & then commit
        s = students.query.filter_by(name=name).first()
            s.city = request.form['city']
            s.addr = request.form['addr']
            s.pin = request.form['pin']
            db.session.commit()

For deleting we need to call db.session.delete on student object to be deleted
    s = students.query.filter_by(name=sname).first()
    db.session.delete(s)
    db.session.commit()

Projects code can be viewed at https://github.com/gitsangramdesai/flask-orm-crud

No comments:

Post a Comment