In the age of Online Education, online examination is a very essential application of EduTech industry. If you have appeared for some kind of online examination or competitive test, you must be wondering how easy or how difficult it is to make such an app. Well, it is not that difficult. In this post we will make you understand how to create a simple Online Quiz App using Flask and PostgreSQL.
Database Table for Online Quiz App
This is a simple application of the level of a minor project for beginners in Flask. So, only one table is used for storing subject wise questions required for the online quiz. Each question is identified by an ID and subject. The last two field in the table are used to apply color to the button representing the question in dashboard and ‘disabled’ status of the button.

Working of the Application
The index page of the application displays blocks with name of the subjects for which quizzes are available. These blocks get the subject names from questions table. The questions table is used to get the distinct subjects which are then passed to the index page using render_tamplate for displaying the clickable blocks of subjects to be chosen by a user.
After a user selects a subject, she is taken to the dashboard where all the questions of the selected subject are displayed as red buttons with question number in the left panel. The first question is displayed in the right panel with the possible answers as radio buttons and a “Save Answer “ button. A user can select any question represented by red color button.
When a user selects an answer from the options and clicks on the “Save Answer” Button that button on left panel for that question becomes green and is disabled. When the user clicks button ”Display Result” from the left panel, the final screen is displayed with a message displaying correct number of answers. “Go to Home Page” button takes back to index page where a user can attempt another quiz
models.py
import os from flask import Flask from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() class questions(db.Model): __tablename__="questions" qid = db.Column(db.Integer, primary_key=True) subject =db.Column(db.String, nullable=False) question =db.Column(db.String, nullable=False) option1 = db.Column(db.String, nullable=True) option2 = db.Column(db.String, nullable=True) option3 = db.Column(db.String, nullable=True) option4 = db.Column(db.String, nullable=True) answer = db.Column(db.Integer, nullable=True) bcol = db.Column(db.String, nullable=True)
application.py
from flask import Flask, render_template, jsonify, request,redirect,flash,session from models import * folder_name="static" app = Flask(__name__) app.config["SQLALCHEMY_DATABASE_URI"] = "postgresql://postgres:yourpasswrodhere @localhost:5432/OnlineQuiz" app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False app.secret_key = b'hkahs3720/' # use a random string app.config["SESSION_PERMANENT"] = False app.config["SESSION_TYPE"] = "filesystem" db.init_app(app) #to change color of question buttons and disable def setStatus(qlist): qAttempt=[] strval=session['result'].strip() ans=strval.split(',') for i in range(int(len(ans)/2)): qAttempt.append(int(ans[2*i])) for rw in qlist: if rw.qid in qAttempt: rw.bcol='green' # set color rw.status='disabled' # disable @app.route("/") def index(): session['result']="" subList=questions.query.with_entities(questions.subject).distinct() return render_template("index.html",subList=subList) @app.route('/quiz', methods=["POST"]) def quiz(): subject= request.form.get('sub') questList=questions.query.filter_by(subject=subject).all() quest=questions.query.filter_by(subject=subject).first() return render_template("dashboard.html",questList=questList, quest=quest) @app.route("/showQuest/<string:subject>,<int:qid>") def showQuest(subject,qid): questList=questions.query.filter_by(subject=subject).all() quest=questions.query.filter_by(qid=qid).first() setStatus(questList) return render_template("dashboard.html",questList=questList, quest=quest) @app.route('/saveAns',methods=["POST"]) def saveAns(): qid=request.form.get('qid') ans=request.form.get('answer') sub=request.form.get('subject') #update the question id and its selected answer in session variable result res=session['result'] res= res+qid+','+ans+',' session['result']=res questList=questions.query.filter_by(subject=sub).all() setStatus(questList) quest=questions.query.filter_by(qid=qid).first() return render_template("dashboard.html",questList=questList, quest=quest) @app.route("/logout") def logout(): #calculate result count=0 txt="" strval=session['result'].strip() #split result string by ',' ans=strval.split(',') for i in range(int(len(ans)/2)): qd=ans[2*i] # get question id qn=ans[2*i+1] # get the sorresponding answer tt=int(qd) quest=questions.query.filter_by(qid=tt).first() actans=quest.answer if actans==int(qn):#compare correct answer in questions table with answer chosen by user count=count+1 # increment counter txt=txt+'You have '+ str(count)+ ' correct questions out of '+ str(int(len(ans)/2))+ ' questions ' # set the result statement return render_template("result.html",txt=txt)
index.html
{% extends "layout_reg.html" %} {% block title %} The Variety Quiz Portal {% endblock %} {% block pagetitle %} Choose a Subject {% endblock %} {% block body %} <form method="POST" action={{url_for('quiz')}}> {% for sb in subList %} <input type="submit" name="sub" value='{{sb.subject}}' style="height:150px; width:150px;border: 1px solid; word-wrap:normal; margin:10px; padding: 10px; box-shadow: 5px 10px 10px #888888;"> {% endfor %} </form> {% endblock %}

quiz.html
{% block title %} Static Files Example {% endblock %} {% block body %} {% for q in questList %} <a href="{{url_for('quiz',sub=q.subject,qid=q.qid)}}"><button>{{q.qid}}</button></a> {% endfor %} {% endblock %}
Dashboard.html
{% extends "layout.html" %} {% block title %} User Dashboard! {% endblock %} {% block pagetitle %} Quiz for :{{quest.subject}} {% endblock %} {% block questList %} <B> Your Questions</B><br><br> {% for q in questList %} <a href="{{url_for('showQuest',subject=q.subject,qid=q.qid)}}"><button value={{q.qid}} {{q.status}} id={{q.qid}} style="margin:2px; width:40px; height:40px;background-color:{{q.bcol}}" >{{loop.index}}</button></a> {% endfor %} <br><br><a href="{{url_for('logout')}}"><button>Display Result</button></a> {% endblock %} {% block content %} <form method="POST" action={{url_for('saveAns')}}> <div class="question"><h5><input type="text" name="qid" value={{quest.qid}} style="border-style:none; width:20px"> <input type="text" name="subject" value='{{quest.subject}}' style="border-style:none"> </h5></div> <div class="qst">{{quest.question}}</div> <div class="opt"><input type="radio" name="answer" value="1"> {{quest.option1}}</div> <div class="opt"><input type="radio" name="answer" value="2"> {{quest.option2}}</div> <div class="opt"><input type="radio" name="answer" value="3"> {{quest.option3}}</div> <div class="opt"><input type="radio" name="answer" value="4"> {{quest.option4}}</div> <input type="submit" value="Save Answer"/> </form> {% endblock %} <script> function colorbtn(bid) { document.getElementByid(bid).background-color = "green"; } </script>


Possible future enhancements of the App
The Online Quiz App is created in its simplest form. It can be extended by adding following features
- Adding time constraint for each question or online Quiz on the whole
- Making it a User login based application and maintaining the record of users about what quizzes they have attempted along with date of attempt and score.
- The Online Quiz App in this form does not allow modifying answer for an attempted question. It can be enhanced to allow this.
to learn how to create an application using Flask and PostgreSQl click here
Be First to Comment