Back to Blog
Tutorial

How to Build a Quiz App with Django and QuizAPI

Step-by-step guide to building a quiz application with Django using the QuizAPI REST API. Fetch questions, render a quiz UI, and submit scores.

Bobby Iliev2026-04-088 min read
Share:

Overview

In this tutorial, you'll build a Django quiz application that pulls questions from QuizAPI and lets users take quizzes directly in your Django app. By the end, you'll have a working quiz page that fetches questions, tracks answers, and submits scores.

Prerequisites

  • Python 3.10+
  • Django 5.x installed
  • A QuizAPI account and API key (get one free at quizapi.io)
  • Basic familiarity with Django views and templates

Project Setup

Create a new Django project and app:

django-admin startproject quizproject cd quizproject python manage.py startapp quizzes pip install requests

Add quizzes to INSTALLED_APPS in settings.py, and add your API key:

# settings.py QUIZAPI_KEY = "your-api-key-here" QUIZAPI_BASE_URL = "https://quizapi.io/api/v1"

Fetching Quizzes from the API

Create a service layer to talk to QuizAPI:

1# quizzes/services.py 2import requests 3from django.conf import settings 4 5def get_quizzes(limit=10, category=None): 6 """Fetch published quizzes from QuizAPI.""" 7 params = {"limit": limit} 8 if category: 9 params["category"] = category 10 11 response = requests.get( 12 f"{settings.QUIZAPI_BASE_URL}/quizzes", 13 headers={"Authorization": f"Bearer {settings.QUIZAPI_KEY}"}, 14 params=params, 15 ) 16 response.raise_for_status() 17 return response.json()["data"] 18 19def get_quiz_questions(quiz_id): 20 """Fetch questions for a specific quiz.""" 21 response = requests.get( 22 f"{settings.QUIZAPI_BASE_URL}/questions", 23 headers={"Authorization": f"Bearer {settings.QUIZAPI_KEY}"}, 24 params={"quizId": quiz_id}, 25 ) 26 response.raise_for_status() 27 return response.json()["data"]

Building the Views

1# quizzes/views.py 2from django.shortcuts import render 3from .services import get_quizzes, get_quiz_questions 4 5def quiz_list(request): 6 quizzes = get_quizzes(limit=20) 7 return render(request, "quizzes/list.html", {"quizzes": quizzes}) 8 9def quiz_play(request, quiz_id): 10 questions = get_quiz_questions(quiz_id) 11 return render(request, "quizzes/play.html", { 12 "quiz_id": quiz_id, 13 "questions": questions, 14 }) 15 16def quiz_results(request): 17 if request.method != "POST": 18 return render(request, "quizzes/results.html", {"score": 0, "total": 0}) 19 20 # Calculate score from submitted answers 21 score = 0 22 total = 0 23 for key, value in request.POST.items(): 24 if key.startswith("question_"): 25 total += 1 26 # value is the answer ID, check if it matches the correct answer 27 correct = request.POST.get(f"correct_{key}", "") 28 if value == correct: 29 score += 1 30 31 percentage = round((score / total) * 100) if total > 0 else 0 32 return render(request, "quizzes/results.html", { 33 "score": score, 34 "total": total, 35 "percentage": percentage, 36 })

Creating the Templates

Quiz List

1<!-- templates/quizzes/list.html --> 2{% extends "base.html" %} 3{% block content %} 4<h1>Available Quizzes</h1> 5<div class="quiz-grid"> 6 {% for quiz in quizzes %} 7 <div class="quiz-card"> 8 <h2>{{ quiz.title }}</h2> 9 <p>{{ quiz.description }}</p> 10 <span class="badge">{{ quiz.difficulty }}</span> 11 <span class="badge">{{ quiz.questionCount }} questions</span> 12 <a href="{% url 'quiz_play' quiz.id %}" class="btn">Play Quiz</a> 13 </div> 14 {% endfor %} 15</div> 16{% endblock %}

Quiz Play

1<!-- templates/quizzes/play.html --> 2{% extends "base.html" %} 3{% block content %} 4<form method="post" action="{% url 'quiz_results' %}"> 5 {% csrf_token %} 6 {% for q in questions %} 7 <div class="question-card"> 8 <h3>{{ forloop.counter }}. {{ q.text }}</h3> 9 {% for answer in q.answers %} 10 <label class="answer-option"> 11 <input type="radio" 12 name="question_{{ q.id }}" 13 value="{{ answer.id }}" 14 required> 15 {{ answer.text }} 16 </label> 17 {% endfor %} 18 <!-- Store correct answer ID in a hidden field --> 19 {% for answer in q.answers %} 20 {% if answer.isCorrect %} 21 <input type="hidden" 22 name="correct_question_{{ q.id }}" 23 value="{{ answer.id }}"> 24 {% endif %} 25 {% endfor %} 26 </div> 27 {% endfor %} 28 <button type="submit" class="btn">Submit Answers</button> 29</form> 30{% endblock %}

URL Configuration

1# quizzes/urls.py 2from django.urls import path 3from . import views 4 5urlpatterns = [ 6 path("", views.quiz_list, name="quiz_list"), 7 path("play/<str:quiz_id>/", views.quiz_play, name="quiz_play"), 8 path("results/", views.quiz_results, name="quiz_results"), 9]
1# quizproject/urls.py 2from django.urls import path, include 3 4urlpatterns = [ 5 path("quizzes/", include("quizzes.urls")), 6]

Running the App

python manage.py runserver

Visit http://localhost:8000/quizzes/ to see your quiz list. Click any quiz to play it, and submit your answers to see your score.

Next Steps

  • Add user authentication to save scores per user
  • Cache API responses with Django's cache framework to reduce API calls
  • Add category filtering to the quiz list
  • Style with Tailwind CSS or Bootstrap for a polished look
  • Use the QuizAPI leaderboard endpoint to show high scores

Resources

Test Your Knowledge

Think you understand Tutorial? Put your skills to the test with hands-on quiz questions.

Tutorial
Start Practicing

Enjoyed this article?

Share it with your team or try our quiz platform.

Stay Updated

Get the latest tutorials and API tips delivered to your inbox.

No spam, unsubscribe anytime.