Flask Contact List App

The Flask Contact List App is a small project to allow a person to store the contacts information. This is the simple project for Flask coding beginners to understand how a small project can be developed using Flask and PostgreSQL.  The Flask Contact List App presents an input form to the user where the user can input the name, contact numbers and email ID of people you want store details of. You can also store the company name and job title of the contact.

All the added contacts are displayed in a table in this single page application. Each row of the record displayed has a “SHOW” link at the end. When a user clicks the show link, the corresponding record is displayed in the input form.

Data Table

The database of this application has only one table “contacts” table. It has the following structure-

CREATE TABLE public.contacts
(
    "contactID" integer NOT NULL DEFAULT nextval('"contacts_contactID_seq"'::regclass),
    "fName" character varying(30) COLLATE pg_catalog."default" NOT NULL,
    "lName" character varying(30) COLLATE pg_catalog."default",
    "mName" character varying(30) COLLATE pg_catalog."default",
    "workCompany" character varying(50) COLLATE pg_catalog."default",
    mobile character varying(20) COLLATE pg_catalog."default",
    "homePhone" character varying(20) COLLATE pg_catalog."default",
    "workPhone" character varying(20) COLLATE pg_catalog."default",
    email character varying(50) COLLATE pg_catalog."default",
    "jobTitle" character varying(50) COLLATE pg_catalog."default",
    CONSTRAINT contacts_pkey PRIMARY KEY ("contactID")
)

Input Form

The input form of Flask Contact List App contains the fields such as first name, middle name, last name, company name, job title, phone numbers and email ID. On clicking the “SUBMIT” button the data from the form fields is sent to addContact route. It uses the model definition of the table to store the data. The last record stored is displayed back in the form.

Flask Contact List App

The data stored in the table is displayed in a table in the second half of the page using the table tag along with Jinja for loop. The “SHOW” link is created in the table by defining it as a link with contactID as key. Whenever the link is clicked the contactID of the selected contact is passed on to fetch that record and is displayed in the form on the left side.   

application.py

from flask import Flask, render_template, jsonify, request, redirect
from models import *
from werkzeug.utils import secure_filename
folder_name="static"

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "postgresql://postgres:********@localhost:5432/contactlist"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
app.config["TARGET_FOLDER"] = "images"
db.init_app(app)


@app.route("/")
def index():
    contList=Contacts.query.all()
    cont=Contacts.query.first()
    return render_template("index.html", cont=cont, contList=contList)
    
@app.route("/addcontact", methods=["POST"])
def addcontact():
    #store values recieved from HTML form in local variables
    fName=request.form.get("FirstName")
    lName=request.form.get("LastName")
    mName=request.form.get("MiddleName")
    workCompany=request.form.get("WorkCompany")
    jobTitle=request.form.get("WorkJobTitle")
    mobile=request.form.get("Mobile")
    homePhone=request.form.get("HomePhone")
    workPhone=request.form.get("WorkPhone")
    email=request.form.get("email")
    #Pass on the local values to the corresponfding model
    contact = Contacts( fName=fName, lName=lName,mName=mName,workCompany=workCompany, jobTitle=jobTitle,mobile=mobile, homePhone=homePhone,workPhone=workPhone,email=email)
    db.session.add(contact)
    db.session.commit()
    cont=Contacts.query.filter_by(contactID=conid).last()
    contList=Contacts.query.all()
    return render_template("index.html",cont=cont, contList=contList) 
    
@app.route("/showContact/<int:conid>")
def showContact(conid):
    # select row from contacts table for contact ID passed from main page
    cont=Contacts.query.filter_by(contactID=conid).first()
    contList=Contacts.query.all()
    return render_template("index.html",cont=cont, contList=contList)    

index.html

{% extends "layout_reg.html" %}

{% block title %}
    Contact List!
{% endblock %}

{% block body %}
 	<form action="{{ url_for('addcontact')}}" method="POST"> 
		<div class="form-group"><h5><center>Contact Details</center></h5></div>
		
		<div class="form-group">
            <input class="form-control" type="text" name="FirstName" placeholder="First Name" value="{{cont.fName}}">
        </div>
		<div class="form-group">
            <input class="form-control" type="text" name="MiddleName" placeholder="Middle Name" value="{{cont.mName}}">
        </div>
		<div class="form-group">
            <input class="form-control" type="text" name="LastName" placeholder="Last Name" value="{{cont.lName}}">
        </div>
		<div class="form-group">
            <input class="form-control" type="text" name="WorkCompany" placeholder="Work Company" value="{{cont.workCompany}}">
        </div>
		<div class="form-group">
            <input class="form-control" type="text" name="WorkJobTitle" placeholder="Job Title" value="{{cont.jobTitle}}">
        </div>
		<div class="form-group">
            <input class="form-control" type="text" name="Mobile" placeholder="Mobile" value="{{cont.mobile}}">
        </div>
		<div class="form-group">
            <input class="form-control" type="text" name="HomePhone" placeholder="Home Phone" value="{{cont.homePhone}}">
        </div>
		<div class="form-group">
            <input class="form-control" type="text" name="WorkPhone" placeholder="Work Phone" value="{{cont.workPhone}}">
        </div>
		<div class="form-group">
            <input class="form-control" type="text" name="email" placeholder="Email" value="{{cont.email}}">
        </div>
		<div class="form-group">
			<center><button class="btn btn-primary">Submit</button></center>
		</div>
		</form>
	{% endblock %}
	{% block content %}
	
	<table class="table">
	<TH>
	<TD><b>Name</b></TD>
	<TD><b>Company</b></TD>
	<TD><b>Job Title</b></TD>
	<TD><b>Phones</b></TD>
	<TD><b>Email</b></TD>
	<TD></TD>
	</TH>
	{% for cl in contList %}
	<TR>
	<TD></TD>
	<TD>{{cl.fName}} {{cl.mName}} {{cl.lName}}</TD>
	<TD>{{cl.workCompany}}</TD>
	<TD>{{cl.jobTitle}}</TD>
	<TD><b>Mobile:</b>{{cl.mobile}}<br><b>Work:</b>{{cl.workPhone}}<br><b>Work:</b>{{cl.homePhone}}</TD>
	<TD>{{cl.email}}</TD>
	<TD><a href="{{url_for('showContact', conid=cl.contactID)}}">Show</a></TD>
	</TR>
	{% endfor %}
	</table>
	{% endblock %}
  </div>
</div>

models.py

import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()
   
class Contacts(db.Model):
    __tablename__="contacts"
    contactID = db.Column(db.Integer, primary_key=True)
    fName =db.Column(db.String, nullable=False)
    lName =db.Column(db.String, nullable=False)
    mName =db.Column(db.String, nullable=False)
    workCompany = db.Column(db.String, nullable=True)
    mobile =db.Column(db.String, nullable=False)
    homePhone =db.Column(db.String, nullable=False)
    workPhone =db.Column(db.String, nullable=False)
    email = db.Column(db.String, nullable=True)
    jobTitle = db.Column(db.String, nullable=True) 

layout_reg.html

<!DOCTYPE html>
<html>
    <head>
        <title>{% block title %}{% endblock %}</title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/css/bootstrap.min.css" integrity="sha384-Zug+QiDoJOrZ5t4lssLdxGhVrurbmBWopoEl+M6BdEfwnCJZtKxi1KgxUyJq13dy" crossorigin="anonymous">
    </head>
    <body>
	<div class="container">
		<div class="row"><div class="col-sm-12">
		<center><h3>Contact List</h3></center>
		</div></div>
		<div class="row">
		<div class="col-sm" style="background-color:#ccfff2; margin-top:5%; box-shadow: 3px 3px 2px 3px #888888; padding-top:10px">
		{% block body %}
        {% endblock %}
		</div>
		<div class="col-sm" style="margin-top:5%">
		{% block content %}
		{% endblock %}
		</div>
		
		</div>
	</div>
    </body>
</html>

This is a very basic application. It can be extended by adding the functionality to modify the selected contact.

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *