mardi 23 juin 2020

How to write the answering page view for django quiz app?

I am wrting a mcq app in django and i am a complete beginner. I am having an issue. I am stuck on writing the page for answering a quiz. Every time a user takes the test,i want to create a new Sitting object, and i want to display a questions-choices form of the quiz and use the choices from each questions to fill the user_answer textfield of the Sitting object, all in the same view. How can I do that?

models.py

 from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User 

class Test(models.Model):
    title = models.CharField(max_length=100)
    date_posted=models.DateTimeField(default=timezone.now)
    creator=models.ForeignKey(User,on_delete=models.CASCADE)
    total_marks=models.IntegerField(default=0)

    def get_total_marks(self):
        for question in self.question_set.all():
            self.total_marks+=question.Marks
        return self.total_marks
    def get_correct_answer_list(self):
        correct_answers=[]

        for question in self.question_set.all():
            for choice in question.choice_set.all():
                if choice.is_correct:
                    correct_answers.append(choice)
        return correct_answers
    def __str__(self):
        return self.title

class Question(models.Model):
    test=models.ForeignKey(Test,on_delete=models.CASCADE)
    question_text = models.CharField(max_length=200)
    Marks = models.IntegerField(default=2)

    def get_answer_list(self):
        answer_list=[]

        for choice in enumerate(self.choice_set.all()):
            answer_list.append(choice)
        return answer_list
    def __str__(self):
        return self.question_text
 
class Choice(models.Model):
    question=models.ForeignKey(Question,on_delete=models.CASCADE)
    choice_text=models.CharField(max_length=200)
    is_correct=models.BooleanField()

    def __str__(self):
        return self.choice_text

class Sitting(models.Model):
    student=models.ForeignKey(User,on_delete=models.CASCADE)
    test=models.ForeignKey(Test,on_delete=models.CASCADE)
    score=models.IntegerField(default=0)
    taken_time=models.DateTimeField(default=timezone.now)
    user_answers=models.TextField(blank=True,default='')

    def calculate_score(self):
        user_answers_list=self.user_answers.split(',')
        correct_answers_list=self.test.get_correct_answer_list()
        for (answer,correct) in zip(user_answers_list,correct_answers_list):
            if answer==correct.choice_text:
                self.score+=correct.question.Marks
        return self.score
    

    def get_absolute_url(self):
        return "/%s/result/"%self.id

    def __str__(self):
        return self.student.username+' took '+self.test.title

views.py

from django.shortcuts import render,get_object_or_404
from django.views import generic
from django.urls import reverse
from django.http import HttpResponseRedirect
from django import forms
from .models import Test,Question,Choice,Sitting
from .forms import TestSitForm,QuestionForm
class IndexView(generic.ListView):
    template_name='quiz/index.html'
    context_object_name='latest_tests_list'

    def get_queryset(self):

        return Test.objects.order_by('date_posted')

class AnswerView(generic.edit.CreateView):
    form_class=TestSitForm
    model=Sitting
    
    
        
    def get_success_url(self):
        return reverse('quiz:test-result',kwargs={'pk':self.object.pk})

    def form_valid(self,form):

        form.instance.student=self.request.user
        form.instance.test=Test.objects.get(pk=self.kwargs['pk'])
        
        return super().form_valid(form)

    def get_context_data(self,**kwargs):
        context=super(AnswerView,self).get_context_data(**kwargs)
        context["test"]=Test.objects.get(pk=self.kwargs["pk"])
        
        for question in context["test"].question_set.all():
            
            context["question_form"+str(question.pk)]=QuestionForm(question)

        return context  
    template_name='quiz/answer.html'


class ResultView(generic.DetailView):
    model=Sitting
    
    template_name='quiz/result.html'



Aucun commentaire:

Enregistrer un commentaire