Как создать экземпляр викторины из модели m2m?
Я хочу создать приложение викторины, где пользователь может войти в систему и решить вопросы, которые связаны с конкретным предметом. И данные пользователя должны храниться в базе данных. Другими словами, если пользователь решает все вопросы, я должен создать экземпляр викторины для него / нее. Здесь я использовал M2M отношения, где многие пользователи могут решить один предмет или один предмет может быть решен многими пользователями. Когда я создаю экземпляр викторины из панели администратора, он не дает мне ошибку, но я не смог создать его из views.py. Вот моя модель викторины:
from django.contrib.auth.models import User
ANSWER_CHOICES = (
("A", "A"),
("B", "B"),
("C", "C"),
("D", "D"),
)
# Create your models here.
class Subject(models.Model):
name = models.CharField(max_length=150, null=True, blank=True)
teacher = models.CharField(max_length=200, null=True, blank=True)
description = models.CharField(max_length=250, null=True, blank=True)
featured_image = models.ImageField(null=True, blank=True, default='default.jpg')
created = models.DateTimeField(auto_now_add=True)
def __str__(self) -> str:
return str(self.name)
class Meta:
ordering = ['id']
class Quiz(models.Model):
subject = models.ForeignKey(Subject, on_delete=models.CASCADE, null=True, blank=True)
question = models.TextField(null=True, blank=True)
a = models.CharField(max_length=50, null=True, blank=True, unique=True)
b = models.CharField(max_length=50, null=True, blank=True, unique=True)
c = models.CharField(max_length=50, null=True, blank=True, unique=True)
d = models.CharField(max_length=50, null=True, blank=True, unique=True)
options = models.CharField(max_length=50, choices=ANSWER_CHOICES, blank=True, null=True, default='A')
answer = models.CharField(max_length=50, blank=True, null=True)
submitted = models.BooleanField(default=False)
def __str__(self) -> str:
return str(self.question)
class Meta:
ordering = ['question']
class QuizInstance(models.Model):
username = models.CharField(max_length=200, null=True, blank=True)
taker = models.ManyToManyField(User)
quiz = models.ManyToManyField(Subject)
quiz_taken = models.DateTimeField(auto_now_add=True)
score = models.IntegerField(default=0)
complete = models.BooleanField(default=False, null=True, blank=True)
def __str__(self) -> str:
return str('Exam Test')
Кроме того, я хочу показать результат викторины, когда она будет завершена. Поэтому я создал var score, но что бы я не делал, я не смог реализовать.
моя модель views.py:
from django.shortcuts import render, redirect
from .models import Subject, Quiz
from django.core.paginator import Paginator
from django.http import HttpResponse
from .forms import AnswerOptionsForm
from .models import QuizInstance
from django.contrib.auth.decorators import login_required
# Create your views here.
def homePage(request):
return render(request, 'home.html')
def quizCard(request):
subjects = Subject.objects.all()
context = {'subjects': subjects}
return render(request, 'quiz-card.html', context)
@login_required(login_url='sign-in')
def getQuestion(request, id):
subject = Subject.objects.get(id=id)
form = AnswerOptionsForm()
obj = subject.quiz_set.all()
p = Paginator(obj, 1)
submitted = False
try:
page = int(request.GET.get('page', '1'))
except:
page = 1
try:
questions = p.page(page)
except(EmptyPage, InvalidPage):
return redirect('result', int(subject.id))
page = p.num_pages
if request.method == 'POST':
submitted = True
currentQuestion = Quiz.objects.get(id=page)
currentQuestion.submitted = True
ans = request.POST.get('options')
print(ans)
if currentQuestion.answer == ans:
pass
# exam.score += 1
# exam.save()
# print(exam.score)
context = {'obj': obj, 'questions': questions, 'page':page, 'form': form, 'submitted': submitted, 'subject': subject}
return render(request, 'questions.html', context)
def result(request, id):
user = request.user.useraccount
subject = Subject.objects.get(id=id)
number_of_questions = len(subject.quiz_set.all())
user.completed_subject.add(subject)
user.save()
###This is Giving me an error###
exam = QuizInstance.objects.filter(
taker = request.user,
quiz = subject,
)
return HttpResponse(f'You have found out of {number_of_questions}')
def retakeQuiz(request, id):
subject = Subject.objects.get(id=id)
exam = QuizInstance.objects.filter(
taker = request.user,
quiz = subject,
score = 0,
complete = False,
)
exam.score = 0
return redirect('question', id)
user models.py
from django.db import models
from django.contrib.auth.models import User
from quiz.models import Quiz
from quiz.models import Subject
# Create your models here.
class UserAccount(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True)
username = models.CharField(max_length=150, blank=True, null=True)
programming_language = models.CharField(max_length=200, blank=True, null=True)
password = models.CharField(max_length=200, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
email = models.EmailField(max_length=300, blank=True, null=True)
completed_subject = models.ManyToManyField(Subject, default=Subject.objects.all)
def __str__(self) -> str:
return str(self.username)