Online Poll Application using Flask and PostgreSQL

Online poll application is a preferred way to gather opinion of people on some burning questions. You might have participated in many of such opinion polls. So, if you are curious to learn the basic technique to code this application, read along.

The following assumptions has been made to create the Online Poll Application using Flask, SQLAlchemy and PostgreSQL

  • Agencies or individuals should be able to add poll questions and post it for users. Users must be able to give their opinions
  • The opinion poll must be categorized on basic of basic categories of poll topic.
  • Each poll must have a start date and end date so that a poll question must automatically stop from being displayed to users.
  • As soon as a new Poll Question is added, it should be displayed on the portal depending upon its start date. Scheduling of Poll can be done by setting start date in future.
  • When a user expresses her opinion by clicking “Agree”, “Disagree” or “Don’t Know” buttons, the respective poll count must be incremented. It must be stored in the database and displayed on home page.  Storing in data is essential so that it can be displayed if a person revisits the portal.

The application is developed using Flask, SQLAlchemy and PostgreSQL

Creation of Online Poll Application

One table is required to store the poll questions and the opinions expressed by visitors.  The structure is as shown in the image

Opinion Poll table

The portal home page of Online poll application displays a button “Add a New Poll Question”.  It displays the active poll questions posted by different agencies or persons.  Users can click “Agree”, “Disagree” or “Don’t Know” buttons to register their opinions. The opinion registered by the user is updated in data base table and reflected in the portal home page.

Online Poll Home Page

layout.html

<!DOCTYPE html>
<html>
    <head>
        <title>{% block title %}{% endblock %}</title>
	</head>
    <body>
		{% block body %}
        {% endblock %}
    </body>
</html>

models.py

import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()
   
class votes(db.Model):
    __tablename__="votes"
    voteid = db.Column(db.Integer, primary_key=True)
    AgencyName =db.Column(db.String, nullable=False)
    voteQues =db.Column(db.String, nullable=False)
    PostDate =db.Column(db.Date, nullable=True)
    EndDate =db.Column(db.Date, nullable=True)
    Agree = db.Column(db.Integer, nullable=True)
    Disagree = db.Column(db.Integer, nullable=True)
    dontknow = db.Column(db.Integer, nullable=True)
    Category = db.Column(db.String, nullable=True)
    Title = db.Column(db.String, nullable=True)

application.py

from flask import Flask, render_template, jsonify, request,redirect
from datetime import datetime
from models import *

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "postgresql://postgres:manu@1682@localhost:5432/VotingDB"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.secret_key = b'hkahs3720/'
db.init_app(app)


@app.route("/")
def index():
    curdt=datetime.now()
    opinionList=votes.query.filter(votes.PostDate<curdt, votes.EndDate>curdt).order_by("voteid").all()
    return render_template("index.html", opinionList=opinionList)
    
@app.route("/addVoteQues")
def addVoteQues():
    return render_template("addVoteQues.html")
    
@app.route("/saveVoteQues", methods=["POST"])
def saveVoteQues():
    aname = request.form.get("aname")
    title = request.form.get("title")
    vques = request.form.get("vques")
    category = request.form.get("category")
    dop = request.form.get("dos")
    doe = request.form.get("doe")
    vote= votes(AgencyName=aname,voteQues=vques,Title=title,Category=category,PostDate=dop,EndDate=doe,Agree=0,Disagree=0,dontknow=0)
    db.session.add(vote)
    db.session.commit()
    return redirect("/")  
    
@app.route("/savevote/<int:vid>/<string:vote>")
def savevote(vid,vote):
    voteval=0
    op = votes.query.filter_by(voteid=vid).first()
    if vote=="A":
        voteval=op.Agree
        op.Agree=voteval+1
    if vote=="D":
        voteval=op.Disagree
        op.Disagree=voteval+1
    if vote=="N":
        voteval=op.dontknow
        op.dontknow=voteval+1  
    db.session.commit() 
    return redirect("/")  

index.html

{% extends "layout_reg.html" %}

{% block title %}
    Online Poll Portal
{% endblock %}              
<a href="{{url_for('details',bg='AP', cid=b.cityid)}}">{{b.ap}}</a></td>
{% block body %}
	
    <div style="margin-left:5%; margin-top:10%;border:1px; float:left; width:40%">
	<a href={{url_for('addVoteQues')}}><div class="btn">Add a New Opinion Poll</div></a>
	</div>
	<div style="margin-top:20px;border:1px; float:left; width:50%">
	{% for p in opinionList %}
	<div class="tag">{{p.Category}}</div>
	<div style="border: 1px solid; height:180px; padding: 10px; box-shadow: 2px 5px #888888; margin-bottom:5px;">
	<h4>{{p.voteQues}}</h4>
	<div class="res">{{p.Agree}}</div><div class="res">{{p.Disagree}}</div><div class="res">{{p.dontknow}}</div>
	<br><br><hr>
	<a href="{{url_for('savevote', vid=p.voteid,vote='A')}}"><div class="votebtn" style="background-color:#97E68C;">Agree</div></a>
	<a href="{{url_for('savevote', vid=p.voteid,vote='D')}}"><div class="votebtn" style="background-color:#F1948A;">Disagree</div></a>
	<a href="{{url_for('savevote', vid=p.voteid,vote='N')}}"><div class="votebtn" style="background-color:#EFF571;">Can't Say</div></a>
	</div>
	{% endfor %}
	</div>
	
{% endblock %}

When “Add a New Poll Question” button is clicked, the form opens which accepts the poll question. It is saved in the table discussed earlier and the same question is posted on the portal home page.

Opinion Poll Question

addVoteQues.html

{% block body %}
<form action="{{ url_for('saveVoteQues') }}" method="post">
	
	<div style="background-color:yellow; border:1px; margin-left:30%;float:left; width:50% ;height:100%">
	<h3 style="font-family:verdana; font-size:20px; margin:5%;">Details of the Online Poll Question</H3>
	<div class="frm">
	
	<div class="lbl">Polling Agency Name:</div><input class="ctrl" type="text" name="aname"><br>
	<div class="lbl">Title of Poll:</div><input class="ctrl" type="text" name="title"><BR>
	<div class="lbl">Poll Question:</div>
	<textarea class="ctrl" name="vques" rows="5" cols="200"></textarea><BR>
	<br>
	<div class="lbl">Category</div><BR>
	<select class="ctrl" name="category">
        <option value="Social">Social</option>
		<option value="Political">Political</option>
		<option value="Economics">Economics</option>
		<option value="Entertainment">Entertainment</option>
		<option value="Education">Education</option>
		<option value="Environment">Environment</option>
		<option value="Manufacturing">Manufacturing</option>
		<option value="Religion">Religion</option>
	</select>
	<br>
	<div class="lbl">Start Date of Poll</div><input class="ctrl" type="date" name="dos"><br>
	<div class="lbl">End Date of Poll</div><input class="ctrl" type="date" name="doe"><br>
	<div class="lbl"><button class="btn">Save</button></div>
	</div>
	</div>
	</form>
{% endblock %}	

Be First to Comment

Leave a Reply

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