feature/post-test-answers #23
@ -59,7 +59,8 @@ INSTALLED_APPS = [
|
||||
"trials",
|
||||
"answers",
|
||||
"questions",
|
||||
"categories"
|
||||
"categories",
|
||||
"tools"
|
||||
]
|
||||
# AUTHENTICATION_BACKENDS = ['config.authh.SettingsBackend']
|
||||
MIDDLEWARE = [
|
||||
|
@ -16,11 +16,12 @@ Including another URLconf
|
||||
from django.contrib import admin
|
||||
from django.urls import include
|
||||
from django.urls import path
|
||||
from .views import home, welcome
|
||||
from .views import home, welcome, help
|
||||
|
||||
urlpatterns = [
|
||||
path('', welcome, name='welcome'),
|
||||
path('home', home, name='home'),
|
||||
path('help', help, name='help'),
|
||||
path('users/', include("users.urls")),
|
||||
path('questions/', include("questions.urls")),
|
||||
path('answers/', include("answers.urls")),
|
||||
|
@ -7,12 +7,16 @@ from trials.models import Test
|
||||
@login_required
|
||||
def home(request):
|
||||
context = {}
|
||||
# TODO replace
|
||||
#context['tests'] = Test.objects.filter(owner=request.user)
|
||||
context['tests'] = Test.objects.all
|
||||
# context = {
|
||||
# 'latest_question_list': latest_question_list,
|
||||
# }
|
||||
return render(request, 'home.html', context)
|
||||
|
||||
|
||||
@login_required
|
||||
def help(request):
|
||||
return render(request, 'help.html', )
|
||||
|
||||
|
||||
def welcome(request):
|
||||
return render(request, 'welcome.html')
|
||||
|
103
static/style.css
103
static/style.css
@ -1,6 +1,6 @@
|
||||
.sidenav {
|
||||
height: 100%;
|
||||
width: 160px;
|
||||
width: 195px;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
@ -8,6 +8,7 @@
|
||||
background-color: #FF0B7E;
|
||||
overflow-x: :hidden;
|
||||
padding-top: 20px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.sidenav a {
|
||||
@ -38,7 +39,7 @@
|
||||
}
|
||||
|
||||
.main {
|
||||
margin-left: 160px;
|
||||
margin-left: 190px;
|
||||
padding: 0px 40px;
|
||||
}
|
||||
|
||||
@ -66,6 +67,25 @@
|
||||
font-size: 13px;
|
||||
padding-bottom: 15px;
|
||||
color: #808080;
|
||||
/*transform: translate(150%,0%);*/
|
||||
width:100%;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.left {
|
||||
float:left;
|
||||
width: 175px;
|
||||
}
|
||||
|
||||
.center {
|
||||
display: inline-block;
|
||||
margin:0 auto;
|
||||
width: 175px;
|
||||
}
|
||||
|
||||
.right {
|
||||
float:right;
|
||||
width: 175px;
|
||||
}
|
||||
|
||||
.mainTestContainer button {
|
||||
@ -81,6 +101,37 @@
|
||||
transform: translate(200%,0%);
|
||||
}
|
||||
|
||||
|
||||
.doubleButton button{
|
||||
height: 30px;
|
||||
width: 150px;
|
||||
color: #FFF;
|
||||
font-size: 17px;
|
||||
background: #00916E;
|
||||
cursor: pointer;
|
||||
border-radius: 25px;
|
||||
border: none;
|
||||
outline: none;
|
||||
transform: translate(150%,0%);
|
||||
}
|
||||
|
||||
.defaultButton {
|
||||
height: 30px;
|
||||
width: 150px;
|
||||
color: #FFF;
|
||||
font-size: 17px;
|
||||
background: #00916E;
|
||||
cursor: pointer;
|
||||
border-radius: 25px;
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.defaultButton a {
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
.mainTestContainer a {
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
@ -88,6 +139,7 @@
|
||||
|
||||
.mainTestDesc{
|
||||
padding-bottom: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mainTestQuest {
|
||||
@ -263,14 +315,57 @@ background-color:#FF0B7E
|
||||
color: #00916E;
|
||||
}
|
||||
|
||||
.testContent{
|
||||
padding-top: 15px;
|
||||
padding-bottom: 15px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.testContent input[type=submit]{
|
||||
height: 30px;
|
||||
width: 150px;
|
||||
color: #FFF;
|
||||
font-size: 15px;
|
||||
font-size: 17px;
|
||||
background: #00916E;
|
||||
cursor: pointer;
|
||||
border-radius: 25px;
|
||||
border: none;
|
||||
outline: none;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.linkDefault {
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.linkDefault a {
|
||||
color: #00916E;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.newContainer input[type=submit]{
|
||||
height: 30px;
|
||||
width: 150px;
|
||||
color: #FFF;
|
||||
font-size: 17px;
|
||||
background: #00916E;
|
||||
cursor: pointer;
|
||||
border-radius: 25px;
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.editContainer {
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.editContainerLine {
|
||||
padding: 10px 0px 10px 0px;
|
||||
}
|
||||
|
||||
.editContainerSection {
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.editContainerSection h2 {
|
||||
display: inline;
|
||||
}
|
48
templates/addQuestions.html
Normal file
48
templates/addQuestions.html
Normal file
@ -0,0 +1,48 @@
|
||||
{% extends "base.html" %}
|
||||
{% load filters %}
|
||||
{% load rest_framework %}
|
||||
|
||||
|
||||
{% block title %}New Test{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="newContainer">
|
||||
<form method="post">
|
||||
<h1>Add questions</h1>
|
||||
{% for i in number_of_questions|times %}
|
||||
<h2>Question {{i}}</h2>
|
||||
<label for="desc">Description: </label>
|
||||
<input id="desc" type="text" name="desc">
|
||||
<br>
|
||||
<br>
|
||||
<label for="ans1">Answer 1: </label>
|
||||
<input id="ans1" type="text" name="ans1">
|
||||
<br>
|
||||
<br>
|
||||
<label for="ans2">Answer 2: </label>
|
||||
<input id="ans2" type="text" name="ans2">
|
||||
<br>
|
||||
<br>
|
||||
<label for="ans3">Answer 3: </label>
|
||||
<input id="ans3" type="text" name="ans3">
|
||||
<br>
|
||||
<br>
|
||||
<label for="ans4">Answer 4: </label>
|
||||
<input id="ans4" type="text" name="ans4">
|
||||
<br>
|
||||
<br>
|
||||
<label for="category">Correct: </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>
|
||||
<br>
|
||||
<br>
|
||||
{% endfor %}
|
||||
<input type="submit" value="Create test">
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
@ -12,9 +12,11 @@
|
||||
|
||||
<body>
|
||||
<div class="sidenav">
|
||||
<a href="/home">Home</a>
|
||||
<a href="/test/create">Create test</a>
|
||||
<a href="/users/tests">Your tests</a>
|
||||
<a href="{% url 'home' %}">Home</a>
|
||||
<a href="{% url 'newTest' %}">Create test</a>
|
||||
<a href="{% url 'myTests' %}">Your tests</a>
|
||||
<a href="{% url 'solvedTests' %}">Solved tests</a>
|
||||
<a href="{% url 'help' %}">Help</a>
|
||||
<p>Categories</p>
|
||||
<a href="/category/JezykPolski">Język polski</a>
|
||||
<a href="/category/JezykAngielski">Język angielski</a>
|
||||
|
@ -10,15 +10,14 @@
|
||||
{{test.name}}
|
||||
</div>
|
||||
<div class="mainTestMeta">
|
||||
Category: {{test.category}}
|
||||
<div class="left">Category: {{test.category}}</div>
|
||||
<div class="center">Passing score: {{test.passing_score}}</div>
|
||||
<div class="right">Questions: {{test.questions|length}}</div>
|
||||
</div>
|
||||
<div class="mainTestDesc">
|
||||
<!-- TODO 250 words limit-->
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus volutpat scelerisque tortor, id sodales leo finibus id. Vivamus id viverra nunc, ac faucibus metus. Nulla a mauris imperdiet sapien lobortis dapibus. Quisque ornare posuere pulvinar.
|
||||
</div>
|
||||
<div class="mainTestMeta">
|
||||
Passing score: {{test.passing_score}}
|
||||
</div>
|
||||
<button><a href="/tests/{{test.id}}/show">Start</a></button>
|
||||
</div>
|
||||
<br>
|
||||
|
41
templates/createTest.html
Normal file
41
templates/createTest.html
Normal file
@ -0,0 +1,41 @@
|
||||
{% extends "base.html" %}
|
||||
{% load rest_framework %}
|
||||
|
||||
{% block title %}New Test{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="newContainer">
|
||||
<form method="post">
|
||||
<h1>Create test</h1>
|
||||
<label for="name">Name: </label>
|
||||
<input id="name" type="text" name="name" value="New test">
|
||||
<br>
|
||||
<br>
|
||||
<label for="category">Category: </label>
|
||||
<select name="category" id="category">
|
||||
<option value="JezykPolski">Język Polski</option>
|
||||
<option value="JezykAngielski">Język Angielski</option>
|
||||
<option value="JezykNiemiecki">Język Niemiecki</option>
|
||||
<option value="Matematyka">Matematyka</option>
|
||||
<option value="Informatyka">Informatyka</option>
|
||||
<option value="Fizyka">Fizyka</option>
|
||||
<option value="Chemia">Chemia</option>
|
||||
<option value="Biologia">Biologia</option>
|
||||
<option value="Geografia">Geografia</option>
|
||||
<option value="Historia">Historia</option>
|
||||
</select>
|
||||
<br>
|
||||
<br>
|
||||
<label for="questions">Number of questions: </label>
|
||||
<input id="questions" type="number" name="questions" value="10">
|
||||
<br>
|
||||
<br>
|
||||
<label for="passing">Passing score: </label>
|
||||
<input id="passing" type="number" name="passing" value="5">
|
||||
<br>
|
||||
<br>
|
||||
<input type="submit" value="Add questions">
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
48
templates/editTest.html
Normal file
48
templates/editTest.html
Normal file
@ -0,0 +1,48 @@
|
||||
{% extends "base.html" %}
|
||||
{% load rest_framework %}
|
||||
|
||||
{% block title %}{{ test.name }} - Edit{% 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="name"><h2>Name:</h2></label>
|
||||
<input id="name" type="text" name="name" value="New test">
|
||||
</div>
|
||||
</div>
|
||||
{% for question in test.questions.all %}
|
||||
<div class="editContainerSection">
|
||||
<div class="editContainerLine">
|
||||
<label for="desc"><b>Description:</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 }}">Answer {{ 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">Correct: </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="Edit test">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
@ -23,32 +23,31 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="card">
|
||||
<div class="card" style="border: none;">
|
||||
<div class="card-body test_body">
|
||||
<div class="card-header test_title">
|
||||
<div class="card-header test_title" style="background:#00916E; color: #FFF;">
|
||||
{{ test.name }}
|
||||
</div>
|
||||
{% for question in test.questions.all %}
|
||||
|
||||
<div class="question_title">
|
||||
{{ question.description }}
|
||||
</div>
|
||||
<div class="list-group">
|
||||
<form method="post" novalidate>
|
||||
{% for answer in question.answers.all %}
|
||||
<label class="list-group-item">
|
||||
<input class="form-check-input me-1" type="radio" name={{ question.id }} value={{ answer.id }}>
|
||||
{{ answer.description }}
|
||||
</label>
|
||||
{% for question in test.questions.all %}
|
||||
<div class="question_title" style="padding-top:15px; padding-bottom:10px; padding-left:5px;">
|
||||
{{ question.description }}
|
||||
</div>
|
||||
<div class="list-group">
|
||||
{% for answer in question.answers.all %}
|
||||
<label class="list-group-item">
|
||||
<input class="form-check-input me-1" type="radio" name={{ question.id }} value={{ answer.id }}>
|
||||
{{ answer.description }}
|
||||
</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% endfor %}
|
||||
<div class="testContent">
|
||||
<input type="submit" value="Send answers">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<input class="testContent" type="submit" value="Send answers">
|
||||
|
||||
{# <button type="submit" class="testContent" value="Send answers"></button>#}
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
@ -1,48 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{{ test.name }}</title>
|
||||
<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>
|
||||
</head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<div class="card-body test_body">
|
||||
<div class="card-header test_title">
|
||||
{{ test.name }}
|
||||
</div>
|
||||
{% for question in test.questions.all %}
|
||||
|
||||
<div class="question_title">
|
||||
{{ question.description }}
|
||||
</div>
|
||||
|
||||
<div class="list-group">
|
||||
{% for answer in question.answers.all %}
|
||||
<label class="list-group-item">
|
||||
<input class="form-check-input me-1" type="radio" name={{ question.id }} value="">
|
||||
{{ answer.description }}
|
||||
</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
8
templates/help.html
Normal file
8
templates/help.html
Normal file
@ -0,0 +1,8 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Help{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>In the future, there will be an app manual here</h1>
|
||||
{% endblock %}
|
||||
|
@ -10,15 +10,14 @@
|
||||
{{test.name}}
|
||||
</div>
|
||||
<div class="mainTestMeta">
|
||||
Category: {{test.category}}
|
||||
<div class="left">Category: {{test.category}}</div>
|
||||
<div class="center">Passing score: {{test.passing_score}}</div>
|
||||
<div class="right">Questions: {{test.questions|length}}</div>
|
||||
</div>
|
||||
<div class="mainTestDesc">
|
||||
<!-- TODO 250 words limit-->
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus volutpat scelerisque tortor, id sodales leo finibus id. Vivamus id viverra nunc, ac faucibus metus. Nulla a mauris imperdiet sapien lobortis dapibus. Quisque ornare posuere pulvinar.
|
||||
</div>
|
||||
<div class="mainTestMeta">
|
||||
Passing score: {{test.passing_score}} / Questions: {{test.questions|length}}
|
||||
</div>
|
||||
<button><a href="/tests/{{test.id}}/show">Start</a></button>
|
||||
</div>
|
||||
<br>
|
||||
|
@ -16,6 +16,9 @@
|
||||
</p>
|
||||
{% endfor %}
|
||||
<input type="submit" value="Login">
|
||||
<div class="linkDefault">
|
||||
<a href="{% url 'resetPassword' %}">Reset password</a>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
|
@ -1,120 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Login</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" integrity="sha384-gfdkjb5BdAXd+lj+gudLWI+BXq4IuLW5IT+brZEZsLFm++aCMlF1V92rMkPaX4PP" crossorigin="anonymous">
|
||||
|
||||
|
||||
<style>
|
||||
body,
|
||||
html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
background: #7abecc !important;
|
||||
}
|
||||
.user_card {
|
||||
width: 350px;
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
background: #74cfbf;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
padding: 10px;
|
||||
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||
-webkit-box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||
-moz-box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||
border-radius: 5px;
|
||||
|
||||
}
|
||||
|
||||
.form_container {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#form-title{
|
||||
color: #fff;
|
||||
|
||||
}
|
||||
|
||||
.login_btn {
|
||||
width: 100%;
|
||||
background: #33ccff !important;
|
||||
color: white !important;
|
||||
}
|
||||
.login_btn:focus {
|
||||
box-shadow: none !important;
|
||||
outline: 0px !important;
|
||||
}
|
||||
.login_container {
|
||||
padding: 0 2rem;
|
||||
}
|
||||
.input-group-text {
|
||||
background: #f7ba5b !important;
|
||||
color: white !important;
|
||||
border: 0 !important;
|
||||
border-radius: 0.25rem 0 0 0.25rem !important;
|
||||
}
|
||||
.input_user,
|
||||
.input_pass:focus {
|
||||
box-shadow: none !important;
|
||||
outline: 0px !important;
|
||||
}
|
||||
|
||||
#messages{
|
||||
background-color: grey;
|
||||
color: #fff;
|
||||
padding: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="container h-100">
|
||||
<div class="d-flex justify-content-center h-100">
|
||||
<div class="user_card">
|
||||
<div class="d-flex justify-content-center">
|
||||
|
||||
|
||||
<h3 id="form-title">LOGIN</h3>
|
||||
</div>
|
||||
<div class="d-flex justify-content-center form_container">
|
||||
<form method="POST" action="">
|
||||
{% csrf_token %}
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text"><i class="fas fa-user"></i></span>
|
||||
</div>
|
||||
<input type="text" name="username" placeholder="Username..." class="form-control">
|
||||
</div>
|
||||
<div class="input-group mb-2">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text"><i class="fas fa-key"></i></span>
|
||||
</div>
|
||||
<input type="password" name="password" placeholder="Password..." class="form-control" >
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-center mt-3 login_container">
|
||||
<input class="btn login_btn" type="submit" value="Login">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<div class="d-flex justify-content-center links">
|
||||
Don't have an account? <a href="{% url 'register' %}" class="ml-2">Sign Up</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -4,6 +4,8 @@
|
||||
|
||||
{% block content %}
|
||||
<p>You have been logged out successfully</p>
|
||||
<a class="btn btn-primary" href="/home">Home</a>
|
||||
<div class="linkDefault">
|
||||
<a href="{% url 'welcome' %}">Continue</a>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
29
templates/myTests.html
Normal file
29
templates/myTests.html
Normal file
@ -0,0 +1,29 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}My Tests{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Check your tests</h1>
|
||||
{% for test in tests %}
|
||||
<div class="mainTestContainer">
|
||||
<div class="mainTestName">
|
||||
{{test.name}}
|
||||
</div>
|
||||
<div class="mainTestMeta">
|
||||
<div class="left">Category: {{test.category}}</div>
|
||||
<div class="center">Passing score: {{test.passing_score}}</div>
|
||||
<div class="right">Questions: {{test.questions|length}}</div>
|
||||
</div>
|
||||
<div class="mainTestDesc">
|
||||
<!-- TODO 250 words limit-->
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus volutpat scelerisque tortor, id sodales leo finibus id. Vivamus id viverra nunc, ac faucibus metus. Nulla a mauris imperdiet sapien lobortis dapibus. Quisque ornare posuere pulvinar.
|
||||
</div>
|
||||
<div class="doubleButton">
|
||||
<button><a href="/tests/{{test.id}}/show">Start</a></button>
|
||||
<button><a href="/tests/{{test.id}}/edit">Edit</a></button>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
@ -6,10 +6,23 @@
|
||||
<div class="resultContainer ">
|
||||
<img class="resultImage" src="http://kmit.in/emagazine/wp-content/uploads/2018/02/karnataka-results.jpg" alt="Card image cap">
|
||||
<div class="resultBody">
|
||||
<h5 class="resultMsg">Quite good! All the best for next quiz!</h5>
|
||||
<h5 class="resultMsg">
|
||||
Quite good! All the best for next quiz!
|
||||
<!-- {% if max_score == 100 %}-->
|
||||
<!-- Idealnie, widzę że ten temat nie ma dla ciebie tajemnic! -->
|
||||
<!-- {% elif max_score >= 75 %}-->
|
||||
<!-- Bardzo dobrze, ale są jeszcze pewne braki ;)-->
|
||||
<!-- {% elif max_score >= 50 %}-->
|
||||
<!-- Nie jest źle, wiedziałeś więcej niż mniej-->
|
||||
<!-- {% elif max_score >= 25 %}-->
|
||||
<!-- Masz spore braki, powinieneś trochę więcej się pouczyć-->
|
||||
<!-- {% else %}-->
|
||||
<!-- Słabiutko, ale następnym razem będzie lepiej-->
|
||||
<!-- {% endif %}-->
|
||||
</h5>
|
||||
<h5 class="resultScore">Result: {{ status }}</h5>
|
||||
<h5 class="resultScore">Score: {{ points }}</h5>
|
||||
<a class="btn btn-primary" href="/home">Home</a>
|
||||
<button class="defaultButton"><a href="{% url 'home' %}">Home</a></button>
|
||||
{# <p class="resultText">Percentage: 60%</p>#}
|
||||
{# <p class="resultText">Correct answers: 3</p>#}
|
||||
{# <p class="resultText">Incorrect answers: 2</p>#}
|
||||
|
0
tools/templatetags/__init__.py
Normal file
0
tools/templatetags/__init__.py
Normal file
6
tools/templatetags/filters.py
Normal file
6
tools/templatetags/filters.py
Normal file
@ -0,0 +1,6 @@
|
||||
from django import template
|
||||
register = template.Library()
|
||||
|
||||
@register.filter(name='times')
|
||||
def times(number):
|
||||
return range(number)
|
@ -38,4 +38,5 @@ class PasswordResetConfirmShortcut:
|
||||
if serializer.is_valid():
|
||||
return Response({"detail": cons.PASSWORD_HAS_BEEN_CHANGED}, status=status.HTTP_200_OK)
|
||||
else:
|
||||
return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
@ -4,7 +4,7 @@ from rest_framework.routers import DefaultRouter
|
||||
from trials.views import TestModelViewSet
|
||||
from trials.views import TestTemplateView
|
||||
from trials.views import TestValidateAPIView
|
||||
from trials.views import TestResultView
|
||||
from trials.views import TestResultView, addTest, addQuestions, myTests, editTest, solvedTests, EditTestTemplateView
|
||||
|
||||
router = DefaultRouter(trailing_slash=False)
|
||||
router.register("items", TestModelViewSet)
|
||||
@ -12,7 +12,12 @@ router.register("items", TestModelViewSet)
|
||||
urlpatterns = [
|
||||
path('<int:test_id>/show', TestTemplateView.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('add/test', addTest, name="newTest"),
|
||||
path('add/questions', addQuestions, name="addQuestions"),
|
||||
path('my', myTests, name="myTests"),
|
||||
path('solved', solvedTests, name="solvedTests")
|
||||
]
|
||||
|
||||
urlpatterns += router.urls
|
||||
|
104
trials/views.py
104
trials/views.py
@ -1,3 +1,4 @@
|
||||
import requests
|
||||
from django.views.generic import TemplateView
|
||||
from rest_framework import views
|
||||
from rest_framework import viewsets
|
||||
@ -6,15 +7,118 @@ from rest_framework.response import Response
|
||||
from trials.models import Test
|
||||
from trials.serializers import TestSerializer
|
||||
from django.conf import settings
|
||||
from django.shortcuts import render, redirect
|
||||
from django import template
|
||||
from django.http import HttpResponseRedirect, HttpResponse
|
||||
from django.template import loader
|
||||
from django.template.loader import render_to_string, get_template
|
||||
from django.http import HttpRequest
|
||||
import requests
|
||||
|
||||
|
||||
def addTest(request):
|
||||
if request.POST:
|
||||
data = request.POST
|
||||
return addQuestions(request="GET", data_about_test=data)
|
||||
return render(request, 'createTest.html')
|
||||
|
||||
|
||||
def addQuestions(request, data_about_test):
|
||||
number_of_question = 0
|
||||
if request == "GET":
|
||||
for key, value in data_about_test.items():
|
||||
if key == "questions":
|
||||
number_of_question = int(value)
|
||||
context = {
|
||||
"number_of_questions": number_of_question
|
||||
}
|
||||
template_name = "addQuestions.html"
|
||||
template = get_template(template_name)
|
||||
return HttpResponse(template.render(context))
|
||||
# return render(response, 'addQuestions.html')
|
||||
|
||||
if request.POST:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
def myTests(request):
|
||||
context = {}
|
||||
# context['tests']=Test.objects.filter(category=request.user)
|
||||
context['tests']=Test.objects.filter(category="Matematyka")
|
||||
#context['tests'] = Test.objects.all
|
||||
return render(request, 'myTests.html', context)
|
||||
|
||||
|
||||
def solvedTests(request):
|
||||
# TODO implementation
|
||||
context = {}
|
||||
# context['tests']=Test.objects.filter(category=request.user)
|
||||
context['tests']=Test.objects.filter(category="Matematyka")
|
||||
#context['tests'] = Test.objects.all
|
||||
return render(request, 'myTests.html', context)
|
||||
|
||||
|
||||
def editTest(request):
|
||||
pass
|
||||
# TODO
|
||||
|
||||
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"
|
||||
test_id = None
|
||||
|
||||
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 get_score(self, test: Test, answers):
|
||||
return test.get_score(answers)
|
||||
|
||||
def formatted_responses(self, unformatted_json):
|
||||
formatted_response = list()
|
||||
for question, answer in unformatted_json.items():
|
||||
formatted_response.append(
|
||||
{
|
||||
"question": question,
|
||||
"answer": answer
|
||||
}
|
||||
)
|
||||
return formatted_response
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
test = Test.objects.get(id=kwargs.get("test_id"))
|
||||
score = self.get_score(test, self.formatted_responses(request.POST))
|
||||
status = score >= test.passing_score
|
||||
context = {
|
||||
"status": self.PASSED.get(status, self.UNKNOWN),
|
||||
"points": score
|
||||
}
|
||||
template_name = "result.html"
|
||||
template = get_template(template_name)
|
||||
return HttpResponse(template.render(context))
|
||||
|
||||
|
||||
class TestModelViewSet(viewsets.ModelViewSet):
|
||||
queryset = Test.objects.all()
|
||||
serializer_class = TestSerializer
|
||||
|
||||
|
||||
class TestTemplateView(TemplateView):
|
||||
PASSED = "passed"
|
||||
FAILED = "failed"
|
||||
|
Loading…
Reference in New Issue
Block a user