1

I am new to django. I am trying to build an Quiz web application that puts one question at a time and as soon as student select one answer on radio button, it immediately shows response whether his answer is correct or incorrect.

If incorrect, it shows them the right answer. Then after clicking on the submit button next question appears. After the last question, result is displayed.

I have 2 problems-

1.My first problem is I am not able to put one question at a time from all set of questions. However I am able to put all questions at a time. How can I do that?

2.My second problem is that I don't know how I will go to next question after clicking on the submit button. Below are my files. Please help me with this.

Images in Working Sequence- 1.Home Page 2.Selecting Quiz1 3.quiz1.html page showing quiz rules 4.home1.html page showing all Questions 5.result.html page showing result

#models.py

from django.db import models

# Create your models here.

class QuesModel(models.Model):
    question=models.CharField(max_length=200,null=True)
    op1=models.CharField(max_length=200,null=True)
    op2=models.CharField(max_length=200,null=True)
    op3=models.CharField(max_length=200,null=True)
    op4=models.CharField(max_length=200,null=True)
    ans=models.CharField(max_length=200,null=True)
    

    def __str__(self):
        return self.question

#views.py

from django.shortcuts import render
from Quiz import models
from Quiz.models import QuesModel
from django.views.generic import TemplateView,ListView,DetailView,CreateView,UpdateView,DeleteView

# Create your views here.


def ques(request):

    if request.method=="POST":

        print(request.POST)
        questions=QuesModel.objects.all()
        total=0
        correct=0
        wrong=0
        score=0
        percent=0
        for q in questions:
            c=False
            w=False
            total+=1
            print("Ques: ",request.POST.get(q.question))
            print("Ans: ",q.ans)
            print()

            if q.ans== request.POST.get(q.question):
                c=True
                print("correct ans")

                score+=10
                correct+=1
            else:
                w=True
                print("wrong ans")
                check=True
                wrong+=1
                print("check value: ",check)

            correct_ans=q.ans
            percent=(score/(total*10))*100

            context={'correct_ans':correct_ans,
            'score':score,
            'time': request.POST.get('timer'),
            'correct':correct,
            'wrong':wrong,
            'percent':percent,
            'total':total}


        return render(request,'Quiz/result.html',context)



    else:
        questions=QuesModel.objects.all()
        context={'questions':questions}
        return render(request,'Quiz/home1.html',context)

def home(request):
    return render(request,'Quiz/home.html')

def quiz1(request):
    return render(request,'Quiz/quiz1.html')

def result(request):
    return render(request,'Quiz/result.html')

#Quiz(App)/urls.py

from django.urls import path
from . import views


urlpatterns=[

path('', views.home, name='home'),
path('quiz1', views.quiz1, name='quiz1'),
path('ques/', views.ques, name='ques'),
# path('ques_list/', views.QuestionsListView.as_view(), name='ques_list'),
path('result', views.result, name='result'),
]

#base.html

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <title>Quiz Island</title>
  </head>
  <body>
        <nav class="navbar navbar-expand-lg navbar-light bg-light">
      <div class="container-fluid">
        <a class="navbar-brand" href="{% url 'home' %}">Quiz Island</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav me-auto mb-2 mb-lg-0">
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="{% url 'home' %}">Home</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="{% url 'result' %}">Result</a>
            </li>
            <li class="nav-item dropdown">
              <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                Quizzes
              </a>
              <ul class="dropdown-menu" aria-labelledby="navbarDropdown">
                <li><a class="dropdown-item" href="{% url 'quiz1' %}">Quiz 1</a></li>
                <li><a class="dropdown-item" href="#">Quiz 2</a></li>
                <li><hr class="dropdown-divider"></li>
                <li><a class="dropdown-item" href="#">Something else here</a></li>
              </ul>
            </li>

          </ul>

        </div>
      </div>
    </nav>
    {% block content %}
    {% endblock %}

    <!-- Optional JavaScript; choose one of the two! -->

    <!-- Option 1: Bootstrap Bundle with Popper -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

    <!-- Option 2: Separate Popper and Bootstrap JS -->
    <!--
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script>
    -->
  </body>
</html>

#home1.html


{% extends 'Quiz/base.html' %}

{% block content %}
{% load static %}
<div class="container ">
<h1>Welcome to DataFlair Quiz</h1>

<div align="right " id="displaytimer"><b>Timer: 0 seconds</b></div>

{% for q  in questions%}
      {{forloop.counter}}
     <form method='post' action=''>
        {% csrf_token %}

        <div class="form-group">
          <label for="question">{{q.question}}</label>
        </div>
        <div class="form-check">
            <div class="form-check">
                <input class="form-check-input" type="radio" name="{{q.question}}" id="gridRadios1" value="op1" >
                <label class="form-check-label" for="gridRadios1">
                    {{q.op1}}
                </label>
            </div>
            <div class="form-check">
                <input class="form-check-input" type="radio" name="{{q.question}}" id="gridRadios2" value="op2">
                <label class="form-check-label" for="gridRadios2">
                    {{q.op2}}
                </label>
            </div>
            <div class="form-check">
                <input class="form-check-input" type="radio" name="{{q.question}}" id="gridRadios1" value="op3">
                <label class="form-check-label" for="gridRadios1">
                    {{q.op3}}
                </label>
            </div>
            <div class="form-check">
                <input class="form-check-input" type="radio" name="{{q.question}}" id="gridRadios2" value="op4">
                <label class="form-check-label" for="gridRadios2">
                    {{q.op4}}
                </label>
            </div>
            <br>
        </div>
        {% endfor %}


        <input id='timer' type='hidden' name="timer" value="">
        <br>
        <button type="submit" class="btn btn-primary">Submit</button>
      </form>

    {% block script %}
        <script>

            console.log('hello world')
            const timer=document.getElementById('displaytimer')
            console.log(timer.textContent)
            const inputtag = document.getElementById('timer')

            t=0
            setInterval(()=>{
                t+=1
                timer.innerHTML ="<b>Timer: " +t+" seconds</b>"
                inputtag.value = t
            },1000)
        </script>
    {% endblock script %}

</div>
{% endblock %}

#quiz1.html


{% extends 'Quiz/base.html' %}

{% block content %}
<div class="container">
    <div class="jumbotron">
      <h2>Quiz 1</h2>
      <h4>Rules</h4>
      {{QuesModel.id}}
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
      <a class="btn btn-warning" href="{% url 'ques' %}">Start Quiz</a>
    </div>

</div>



{% endblock %}


#result.html

{% extends 'Quiz/base.html' %}

{% block content %}

<div class="container">
  {% if check %}
    <p>Your ans is wrong, Correct ans is :{{correct_ans}}</p>
  {% endif %}

    <p>Score: {{score}}</p>
    <p>percent: {{percent}}%</p>
    <p>total: {{total}}</p>
    <p>correct: {{correct}}</p>
    <p>wrong: {{wrong}}</p>
    <p>time: {{time}}</p>



</div>
{% endblock %}

Vishal Maurya
  • 21
  • 1
  • 4

2 Answers2

0

will i think the batter way to do this by using ajax from ajax you can make post request to your view with question id like

from django.core import serializers
from django.http import JsonResponse
def GetQuestionView(request):
   if request.method == "POST" and request.is_ajax():
       question_id = request.POST.get("id")
       return JsonResponse(serializers.serialize("json", QuesModel.objects.get(pk=question_id )))
   ...

now from frontend you can make ajax request check out this docs https://docs.djangoproject.com/en/3.2/ref/csrf/ if get csrf token error

harsh 88
  • 1
  • 2
  • Thanks for your concern. Actually bro i don't know about ajax? Is there any simple solution to that by using basic django, plz let me know? – Vishal Maurya Aug 01 '21 at 19:02
0

For your first problem you can pass all model objects in the template and then use index to filter out each question and its options, for your code it should look like

{{ questions.0 }}

in your template will give you the first object in your queryset (question with its options). Using javascript you can now update your questions (just assign a variable as the index and change its value everytime) and its options everytime next question event is fired and display your results

I don't think you need a second view for your second question as you can just use javascript to update the same page.

yashsh
  • 81
  • 11