Merge pull request 'edit tests' (#29) from feauture/edit-test into master

Reviewed-on: #29
This commit is contained in:
s470631 2022-01-30 20:04:51 +01:00
commit 4e3fdfa565
7 changed files with 416 additions and 62 deletions

View File

@ -14,6 +14,7 @@ class QuestionManager(Manager):
**kwargs **kwargs
): ):
Answer = apps.get_model("answers", "Answer") Answer = apps.get_model("answers", "Answer")
instance = super().create( instance = super().create(
name=name, name=name,
test=test, test=test,
@ -27,3 +28,57 @@ class QuestionManager(Manager):
) )
return instance return instance
def addQuestionToExistingTest(
self, *,
answers=[],
name=None,
test=None,
description=None,
**kwargs
):
Answer = apps.get_model("answers", "Answer")
instance = super().create(
name=name,
test=test,
description=name,
)
for answer in answers:
for a in answer["answers"]:
Answer.objects.create(
question=instance,
description=a["description"],
is_correct=a["is_correct"]
)
return instance
def EditQuestion(
self, *,
question_id=None,
answers=[],
name=None,
description=None,
**kwargs
):
Answer = apps.get_model("answers", "Answer")
instance = super().get(
id=question_id
)
instance.name = name
instance.description = name
actual_answers = instance.answers.all()
for answer in actual_answers:
answer.is_correct = False
answer.save()
for i in range(0, len(answers[0]["answers"])):
actual_answer = actual_answers[i]
new_answer = answers[0]["answers"][i]
actual_answer.description = new_answer["description"]
actual_answer.is_correct = new_answer["is_correct"]
actual_answer.save()
instance.save()
return instance

View File

@ -0,0 +1,45 @@
{% extends "base.html" %}
{% load filters %}
{% load rest_framework %}
{#{% block title %}{{ request.GET.name }}{% endblock %}#}
{% block content %}
<div class="newContainer">
<form method="post">
<h1>Dodaj pytanie</h1>
<label for="desc">Opis: </label>
<input id="desc" type="text" name="desc">
<br>
<br>
<label for="ans1">Odpowiedź 1: </label>
<input id="ans1" type="text" name="ans1">
<br>
<br>
<label for="ans2">Odpowiedź 2: </label>
<input id="ans2" type="text" name="ans2">
<br>
<br>
<label for="ans3">Odpowiedź 3: </label>
<input id="ans3" type="text" name="ans3">
<br>
<br>
<label for="ans4">Odpowiedź 4: </label>
<input id="ans4" type="text" name="ans4">
<br>
<br>
<label for="is_correct">Poprawna: </label>
<select name="is_correct" id="is_correct">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<br>
<br>
<input type="submit" value="Dodaj pytanie">
</form>
</div>
{% endblock %}

View File

@ -0,0 +1,39 @@
{% extends "base.html" %}
{% load rest_framework %}
{% block title %}{{ test.name }} - Edytuj{% endblock %}
{% block additional_head %}
<meta charset="UTF-8">
{% endblock %}
{% block content %}
<div class="editContainer">
<form method="post" novalidate>
<div class="editContainerSection">
<div class="editContainerLine">
<label for="desc"><b>Opis:</b></label>
<input id="desc" type="text" name="desc", value="{{ question.description }}">
</div>
{% for answer in question.answers.all %}
<div class="editContainerLine">
<label for="ans-{{ forloop.counter }}">Odpowiedź {{ forloop.counter }}: </label>
<input id="ans-{{ forloop.counter }}" type="text" name="ans{{ forloop.counter }}", value="{{ answer.description }}">
</div>
{% endfor %}
<div class="editContainerLine">
<label for="category">Poprawna: </label>
<select name="is_correct" id="is_correct">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</div>
</div>
<div class="testContent">
<input type="submit" value="Zapisz zmiany">
</div>
</form>
</div>
{% endblock %}

View File

@ -1,48 +1,116 @@
{# <div class="editContainerSection">#}
{# <div class="editContainerLine">#}
{# <label for="name"><h2>Nazwa:</h2></label>#}
{# <input id="name" type="text" name="name" value="{{ test.name }}">#}
{# </div>#}
{# </div>#}
{#{% extends "base.html" %}#}
{#{% load rest_framework %}#}
{##}
{#{% block title %}{{ test.name }} - Edytuj{% endblock %}#}
{##}
{#{% block additional_head %}#}
{# <meta charset="UTF-8">#}
{#{% endblock %}#}
{##}
{#{% block content %}#}
{# <div class="editContainer">#}
{# <form method="post" novalidate>#}
{##}
{# {% for question in test.questions.all %}#}
{# <div class="editContainerSection">#}
{# <div class="editContainerLine">#}
{# <label for="desc"><b>Opis:</b></label>#}
{# <input id="desc" type="text" name="desc", value="{{ question.description }}">#}
{# </div>#}
{# {% for answer in question.answers.all %}#}
{# <div class="editContainerLine">#}
{# <label for="ans-{{ forloop.counter }}">Odpowiedź {{ forloop.counter }}: </label>#}
{# <input id="ans-{{ forloop.counter }}" type="text" name="ans-{{ forloop.counter }}", value="{{ answer.description }}">#}
{# </div>#}
{# {% endfor %}#}
{# <div class="editContainerLine">#}
{# <label for="category">Poprawna: </label>#}
{# <select name="category" id="category">#}
{# <option value="1">1</option>#}
{# <option value="2">2</option>#}
{# <option value="3">3</option>#}
{# <option value="4">4</option>#}
{# </select>#}
{# </div>#}
{# </div>#}
{# {% endfor %}#}
{# <div class="testContent">#}
{# <input type="submit" value="Zapisz test">#}
{# <a href="/tests/{{test.id}}/add-question">Dodaj pytanie</a>#}
{# <a href="/tests/{{test.id}}/remove-question">Usun pytanie</a>#}
{# </div>#}
{# </form>#}
{# </div>#}
{#{% endblock %}#}
{##}
{% extends "base.html" %} {% extends "base.html" %}
{% load rest_framework %} {% load rest_framework %}
{% block title %}{{ test.name }} - Edytuj{% endblock %} {% block title %}{{ test.name }}{% endblock %}
{% block additional_head %} {% block additional_head %}
<meta charset="UTF-8"> <meta charset="UTF-8">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<style>
.test_title {
font-size: 40px;
}
.test_body {
width: 50%;
}
.question_title {
font-size: 20px;
}
</style>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="editContainer"> <div class="card" style="border: none;">
<form method="post" novalidate> <div class="card-body test_body">
<div class="editContainerSection"> <div class="editContainerSection">
<div class="editContainerLine"> <div class="editContainerLine">
<label for="name"><h2>Nazwa:</h2></label> <label for="name"><h2>Nazwa:</h2></label>
<input id="name" type="text" name="name" value="{{ test.name }}"> <input id="name" type="text" name="name" value="{{ test.name }}">
<button class="defaultButton">
<a href='' onclick="this.href='editName?name='+document.getElementById('name').value">Zmien nazwe</a>
</button>
</div> </div>
</div> </div>
<form method="post" novalidate>
{% for question in test.questions.all %} {% for question in test.questions.all %}
<div class="editContainerSection"> <div class="question_title" style="padding-top:15px; padding-bottom:10px; padding-left:5px;">
<div class="editContainerLine"> {{ question.description }}
<label for="desc"><b>Opis:</b></label> <input class="form-check-input me-1" type="radio" name="id" value={{ question.id }}>
<input id="desc" type="text" name="desc", value="{{ question.description }}">
</div> </div>
<div class="list-group">
{% for answer in question.answers.all %} {% for answer in question.answers.all %}
<div class="editContainerLine"> <label class="list-group-item">
<label for="ans-{{ forloop.counter }}">Odpowiedź {{ forloop.counter }}: </label> {{ answer.description }}
<input id="ans-{{ forloop.counter }}" type="text" name="ans-{{ forloop.counter }}", value="{{ answer.description }}"> </label>
</div>
{% endfor %} {% endfor %}
<div class="editContainerLine">
<label for="category">Poprawna: </label>
<select name="category" id="category">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</div>
</div> </div>
{% endfor %} {% endfor %}
<div class="testContent"> <div class="testContent">
<input type="submit" value="Zapisz test"> <input type="submit" value="Edytuj wybrane pytanie">
<a href="/tests/{{test.id}}/add-question">Dodaj pytanie</a>
<a href="/tests/{{test.id}}/remove-question">Usun pytanie</a>
</div> </div>
</form> </form>
</div> </div>
{% endblock %}
</div>
{% endblock %}

View File

@ -0,0 +1,53 @@
{% extends "base.html" %}
{% load rest_framework %}
{% block title %}{{ test.name }}{% endblock %}
{% block additional_head %}
<meta charset="UTF-8">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<style>
.test_title {
font-size: 40px;
}
.test_body {
width: 50%;
}
.question_title {
font-size: 20px;
}
</style>
{% endblock %}
{% block content %}
<div class="card" style="border: none;">
<div class="card-body test_body">
<div class="card-header test_title" style="background:#00916E; color: #FFF;">
Usuń pytanie
</div>
<form method="post" novalidate>
{% for question in test.questions.all %}
<div class="question_title" style="padding-top:15px; padding-bottom:10px; padding-left:5px;">
{{ question.description }}
<input class="form-check-input me-1" type="radio" name="id" value={{ question.id }}>
</div>
<div class="list-group">
{% for answer in question.answers.all %}
<label class="list-group-item">
{{ answer.description }}
</label>
{% endfor %}
</div>
{% endfor %}
<div class="testContent">
<input type="submit" value="Usuń pytanie">
</div>
</form>
</div>
</div>
{% endblock %}

View File

@ -4,7 +4,7 @@ from rest_framework.routers import DefaultRouter
from trials.views import TestModelViewSet from trials.views import TestModelViewSet
from trials.views import TestTemplateView from trials.views import TestTemplateView
from trials.views import TestValidateAPIView from trials.views import TestValidateAPIView
from trials.views import TestResultView, addTest, addQuestions, myTests, editTest, solvedTests, EditTestTemplateView, deleteTest from trials.views import TestResultView, addTest, addQuestions, myTests, editTest, solvedTests, EditTestTemplateView, deleteTest, AddQuestionToExistingTest, RemoveQuestionFromExistingTest, EditQuestionTemplateView, editName
router = DefaultRouter(trailing_slash=False) router = DefaultRouter(trailing_slash=False)
router.register("items", TestModelViewSet) router.register("items", TestModelViewSet)
@ -14,6 +14,10 @@ urlpatterns = [
path('<int:test_id>/mark', TestValidateAPIView.as_view()), path('<int:test_id>/mark', TestValidateAPIView.as_view()),
path('<int:test_id>/result', TestResultView.as_view()), path('<int:test_id>/result', TestResultView.as_view()),
path('<int:test_id>/edit', EditTestTemplateView.as_view()), path('<int:test_id>/edit', EditTestTemplateView.as_view()),
path('<int:test_id>/add-question', AddQuestionToExistingTest.as_view()),
path('<int:test_id>/remove-question', RemoveQuestionFromExistingTest.as_view()),
path('question/<int:question_id>/edit', EditQuestionTemplateView.as_view()),
path('<int:test_id>/editName', editName, name="editName"),
path('<int:test_id>/remove', deleteTest, name="deleteTest"), path('<int:test_id>/remove', deleteTest, name="deleteTest"),
# path('delete', deleteTest, name="deleteTest"), # path('delete', deleteTest, name="deleteTest"),
path('add/test', addTest, name="newTest"), path('add/test', addTest, name="newTest"),

View File

@ -7,6 +7,7 @@ from rest_framework import viewsets
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.views import APIView
from questions.models import Question
from trials.models import Test, SolvedTest from trials.models import Test, SolvedTest
from trials.serializers import TestSerializer from trials.serializers import TestSerializer
from django.conf import settings from django.conf import settings
@ -73,6 +74,67 @@ def addQuestions(request, **kwargs):
return render(request, 'addQuestions.html') return render(request, 'addQuestions.html')
class AddQuestionToExistingTest(TemplateView):
template_name = settings.BASE_DIR + f"/templates/addQuestionToExistingTest.html"
def post(self, request, *args, **kwargs):
answers = []
answer1 = {
"description": dict(request.POST)["ans1"][0],
"is_correct": False
}
answer2 = {
"description": dict(request.POST)["ans2"][0],
"is_correct": False
}
answer3 = {
"description": dict(request.POST)["ans3"][0],
"is_correct": False
}
answer4 = {
"description": dict(request.POST)["ans4"][0],
"is_correct": False
}
is_correct = dict(request.POST)["is_correct"][0]
if is_correct == "1":
answer1["is_correct"] = True
if is_correct == "2":
answer2["is_correct"] = True
if is_correct == "3":
answer3["is_correct"] = True
if is_correct == "4":
answer4["is_correct"] = True
answers.append({
"answers": [
answer1,
answer2,
answer3,
answer4
]
})
description = dict(request.POST)["desc"][0]
Question.objects.addQuestionToExistingTest(name=description, answers=answers, test=Test.objects.get(id=kwargs["test_id"]))
return redirect(f'/tests/{kwargs["test_id"]}/edit')
class RemoveQuestionFromExistingTest(TemplateView):
template_name = settings.BASE_DIR + f"/templates/removeQuestionFromExistingTest.html"
def get_queryset(self):
return Test.objects.all()
def get_context_data(self, test_id, **kwargs):
self.test_id = test_id
context = super().get_context_data(**kwargs)
context["test"] = self.get_queryset().filter(id=test_id).prefetch_related("questions__answers").first()
return context
def post(self, request, *args, **kwargs):
Question.objects.get(id=request.POST["id"]).delete()
return redirect(f'/tests/{kwargs["test_id"]}/edit')
def myTests(request): def myTests(request):
context = {} context = {}
user = request.user.id user = request.user.id
@ -112,18 +174,8 @@ def editTest(request):
class EditTestTemplateView(TemplateView): class EditTestTemplateView(TemplateView):
PASSED = "passed"
FAILED = "failed"
UNKNOWN = "unknown"
PASSED = {
True: PASSED,
False: FAILED
}
permission_classes = []
template_name = settings.BASE_DIR + f"/templates/editTest.html" template_name = settings.BASE_DIR + f"/templates/editTest.html"
test_id = None
def get_queryset(self): def get_queryset(self):
return Test.objects.all() return Test.objects.all()
@ -134,36 +186,74 @@ class EditTestTemplateView(TemplateView):
context["test"] = self.get_queryset().filter(id=test_id).prefetch_related("questions__answers").first() context["test"] = self.get_queryset().filter(id=test_id).prefetch_related("questions__answers").first()
return context return context
def get_score(self, test: Test, answers): def post(self, request, *args, **kwargs):
return test.get_score(answers) return redirect(f'/tests/question/{request.POST["id"]}/edit?test_id={kwargs["test_id"]}')
def formatted_responses(self, unformatted_json):
formatted_response = list() class EditQuestionTemplateView(TemplateView):
for question, answer in unformatted_json.items(): template_name = settings.BASE_DIR + f"/templates/editQuestion.html"
formatted_response.append(
{ def get_queryset(self):
"question": question, return Question.objects.all()
"answer": answer
} def get_context_data(self, question_id, **kwargs):
) context = super().get_context_data(**kwargs)
return formatted_response context["question"] = self.get_queryset().filter(id=question_id).prefetch_related("answers").first()
return context
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
test = Test.objects.get(id=kwargs.get("test_id")) question_id = kwargs["question_id"]
score = self.get_score(test, self.formatted_responses(request.POST)) test = request.GET.get("test_id")
status = score >= test.passing_score answers = []
context = { answer1 = {
"status": self.PASSED.get(status, self.UNKNOWN), "description": dict(request.POST)["ans1"][0],
"points": score "is_correct": False
} }
template_name = "result.html" answer2 = {
template = get_template(template_name) "description": dict(request.POST)["ans2"][0],
return HttpResponse(template.render(context)) "is_correct": False
}
answer3 = {
"description": dict(request.POST)["ans3"][0],
"is_correct": False
}
answer4 = {
"description": dict(request.POST)["ans4"][0],
"is_correct": False
}
is_correct = dict(request.POST)["is_correct"][0]
if is_correct == "1":
answer1["is_correct"] = True
if is_correct == "2":
answer2["is_correct"] = True
if is_correct == "3":
answer3["is_correct"] = True
if is_correct == "4":
answer4["is_correct"] = True
answers.append({
"answers": [
answer1,
answer2,
answer3,
answer4
]
})
description = dict(request.POST)["desc"][0]
Question.objects.EditQuestion(question_id=question_id, name=description, answers=answers)
return redirect(f'/tests/{test}/edit')
def deleteTest(request, test_id): def deleteTest(request, test_id):
Test.objects.filter(id=test_id).delete() Test.objects.filter(id=test_id).delete()
return redirect('myTests') return redirect('myTests')
def editName(request, test_id):
new_name = request.GET["name"]
test = Test.objects.get(id=test_id)
test.name = new_name
test.save()
return redirect(f'/tests/{test_id}/edit')
class TestModelViewSet(viewsets.ModelViewSet): class TestModelViewSet(viewsets.ModelViewSet):
queryset = Test.objects.all() queryset = Test.objects.all()