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.
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
Think you understand Tutorial? Put your skills to the test with hands-on quiz questions.
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.
Related Articles
Building a Quiz Component in React with QuizAPI
Build a reusable React quiz component that fetches questions from QuizAPI, manages quiz state, and displays scores. Full TypeScript implementation included.
Building a Quiz Leaderboard with Real-Time Updates
Build a live quiz leaderboard with ranking algorithms, efficient data models, and real-time delivery using SSE and WebSockets.
Add Quizzes to Your Laravel App with QuizAPI
Integrate QuizAPI into a Laravel application with the HTTP client, Blade templates, and proper form handling for a complete quiz experience.