Start using start dates for exams
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
{% block navigation %}
|
{% block navigation %}
|
||||||
{{block.super}}
|
{{block.super}}
|
||||||
<br/>
|
<br/>
|
||||||
Exams: {{exam.name}}->
|
Exams: {{exam}}->
|
||||||
<a href="{% url 'anatomy:exam_overview' pk=exam.pk %}">Overview</a> /
|
<a href="{% url 'anatomy:exam_overview' pk=exam.pk %}">Overview</a> /
|
||||||
{% if exam.exam_mode %}
|
{% if exam.exam_mode %}
|
||||||
<a href="{% url 'anatomy:mark_overview' pk=exam.pk %}">Mark</a> /
|
<a href="{% url 'anatomy:mark_overview' pk=exam.pk %}">Mark</a> /
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="anatomy">
|
<div class="anatomy">
|
||||||
<h2>Marking exam: {{ exam.name }}</h2>
|
<h2>Marking exam: {{ exam }}</h2>
|
||||||
You can start marking from a particular question by clicking on it below.
|
You can start marking from a particular question by clicking on it below.
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Exams: {% for exam in question.exams.all %}
|
Exams: {% for exam in question.exams.all %}
|
||||||
<a href="{% url 'anatomy:exam_overview' pk=exam.pk %}">{{ exam.name }}</a>
|
<a href="{% url 'anatomy:exam_overview' pk=exam.pk %}">{{ exam }}</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
{% if previous > -1 %}
|
{% if previous > -1 %}
|
||||||
<a href="{% url 'anatomy:exam_question_detail' exam.id previous %}">Previous question</a>
|
<a href="{% url 'anatomy:exam_question_detail' exam.id previous %}">Previous question</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
Viewing question as part of exam: <a href="{% url 'anatomy:exam_overview' exam.id %}">{{exam.name}}</a> [{{pos}}/{{exam_length}}]
|
Viewing question as part of exam: <a href="{% url 'anatomy:exam_overview' exam.id %}">{{exam}}</a> [{{pos}}/{{exam_length}}]
|
||||||
{% if next %}
|
{% if next %}
|
||||||
<a href="{% url 'anatomy:exam_question_detail' exam.id next %}">Next question</a>
|
<a href="{% url 'anatomy:exam_question_detail' exam.id next %}">Next question</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ def test_exams(db, client):
|
|||||||
.find("li", attrs={"data-exam-id": exam.pk})
|
.find("li", attrs={"data-exam-id": exam.pk})
|
||||||
)
|
)
|
||||||
assert search_exam
|
assert search_exam
|
||||||
assert exam.name in str(search_exam)
|
assert str(exam) in str(search_exam)
|
||||||
assert len(search_exam.find("button", {"class": "start-button"})) > 0
|
assert len(search_exam.find("button", {"class": "start-button"})) > 0
|
||||||
# assert "Active" in assigned_exams # check it is active
|
# assert "Active" in assigned_exams # check it is active
|
||||||
|
|
||||||
@@ -319,8 +319,8 @@ def test_exams(db, client):
|
|||||||
.find_all("li", attrs={"data-exam-id": exam.pk})
|
.find_all("li", attrs={"data-exam-id": exam.pk})
|
||||||
)
|
)
|
||||||
assert results_exam
|
assert results_exam
|
||||||
assert exam.name in str(results_exam)
|
assert str(exam) in str(results_exam)
|
||||||
assert exam.name + " test" not in str(results_exam)
|
assert str(exam) + " test" not in str(results_exam)
|
||||||
assert "Results Published" not in str(
|
assert "Results Published" not in str(
|
||||||
results_exam
|
results_exam
|
||||||
) # It should not be published yet
|
) # It should not be published yet
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ from generic.models import (
|
|||||||
CidUserExam,
|
CidUserExam,
|
||||||
CidUserGroup,
|
CidUserGroup,
|
||||||
ExamOrCollectionGenericBase,
|
ExamOrCollectionGenericBase,
|
||||||
|
ExamUserStatus,
|
||||||
Examination,
|
Examination,
|
||||||
# Condition,
|
# Condition,
|
||||||
ExamBase,
|
ExamBase,
|
||||||
@@ -775,6 +776,8 @@ class CaseCollection(ExamOrCollectionGenericBase):
|
|||||||
help_text="If true allows users self complete and review cases in a self directed way.",
|
help_text="If true allows users self complete and review cases in a self directed way.",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
exam_user_status = GenericRelation(ExamUserStatus)
|
||||||
|
|
||||||
feedback_once_collection_complete = models.BooleanField(default=True, help_text="If true feedback is only given once the collection is complete. If false feedback is given after each case.")
|
feedback_once_collection_complete = models.BooleanField(default=True, help_text="If true feedback is only given once the collection is complete. If false feedback is given after each case.")
|
||||||
|
|
||||||
class COLLECTION_TYPE_CHOICES(models.TextChoices):
|
class COLLECTION_TYPE_CHOICES(models.TextChoices):
|
||||||
@@ -996,6 +999,8 @@ class CaseDetail(models.Model):
|
|||||||
|
|
||||||
question_schema = models.JSONField(null=True, blank=True)
|
question_schema = models.JSONField(null=True, blank=True)
|
||||||
question_answers = models.JSONField(null=True, blank=True)
|
question_answers = models.JSONField(null=True, blank=True)
|
||||||
|
# TODO add feedback for questions
|
||||||
|
#question_feedback = models.JSONField(null=True, blank=True)
|
||||||
|
|
||||||
sort_order = models.IntegerField(default=1000)
|
sort_order = models.IntegerField(default=1000)
|
||||||
|
|
||||||
|
|||||||
@@ -177,7 +177,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<details><summary>View questions</summary>
|
<details><summary class="opacity-50">View questions</summary>
|
||||||
{{form.json.errors}}
|
{{form.json.errors}}
|
||||||
<div class="form-contents">
|
<div class="form-contents">
|
||||||
<fieldset {% if question_completed %}disabled="disabled"{% endif %}>
|
<fieldset {% if question_completed %}disabled="disabled"{% endif %}>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{% extends 'atlas/base.html' %}
|
{% extends 'atlas/base.html' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h2>Collection: {{exam.name}}</h2>
|
<h2>Collection: {{exam}}</h2>
|
||||||
|
|
||||||
{% comment %} <ul>
|
{% comment %} <ul>
|
||||||
{% for case in collection.cases.all %}
|
{% for case in collection.cases.all %}
|
||||||
|
|||||||
@@ -9,6 +9,6 @@
|
|||||||
<h3>My cases / collections</h3>
|
<h3>My cases / collections</h3>
|
||||||
View my <a href='{% url "atlas:case_view" %}?author={{request.user.id}}'>cases</a>.<br/>
|
View my <a href='{% url "atlas:case_view" %}?author={{request.user.id}}'>cases</a>.<br/>
|
||||||
|
|
||||||
<a href="{% url 'atlas:user_uploads' %}"><button><i class="bi bi-cloud-arrow-up"></i> Uploads awaiting import</button></a>
|
<a href="{% url 'atlas:user_uploads' %}"><i class="bi bi-cloud-arrow-up"></i> Uploads awaiting import</a>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -1914,6 +1914,16 @@ def collection_take_overview(
|
|||||||
cid_user_exam.completed = True
|
cid_user_exam.completed = True
|
||||||
cid_user_exam.save()
|
cid_user_exam.save()
|
||||||
|
|
||||||
|
if cid is not None:
|
||||||
|
c = CidUser.objects.get(cid=cid)
|
||||||
|
collection.exam_user_status.create(
|
||||||
|
cid_user=c, user_user=None, status="submitted", extra="manual submission"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
collection.exam_user_status.create(
|
||||||
|
cid_user=None, user_user=request.user, status="submitted", extra="manual submission"
|
||||||
|
)
|
||||||
|
|
||||||
return HttpResponse("True")
|
return HttpResponse("True")
|
||||||
else:
|
else:
|
||||||
raise Http404()
|
raise Http404()
|
||||||
|
|||||||
+8
-3
@@ -869,6 +869,14 @@ class ExamBase(ExamOrCollectionGenericBase):
|
|||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
print("TESTING")
|
||||||
|
if self.start_date and self.start_date is not None:
|
||||||
|
print(f"Start date: {self.start_date:%d %B %Y}")
|
||||||
|
return f"{self.name} ({self.start_date:%d %B %Y})"
|
||||||
|
else:
|
||||||
|
return self.name
|
||||||
|
|
||||||
def save(self, *args, recreate_json=True, **kwargs):
|
def save(self, *args, recreate_json=True, **kwargs):
|
||||||
self.recreate_json = recreate_json
|
self.recreate_json = recreate_json
|
||||||
|
|
||||||
@@ -903,9 +911,6 @@ class ExamBase(ExamOrCollectionGenericBase):
|
|||||||
"""
|
"""
|
||||||
return text
|
return text
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse("{}:exam_overview".format(self.app_name), kwargs={"pk": self.pk})
|
return reverse("{}:exam_overview".format(self.app_name), kwargs={"pk": self.pk})
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
Packet:
|
Packet:
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ exam.name }} </a></h1>
|
{{ exam }} </a></h1>
|
||||||
<span class="authors">Authors: {{exam.get_authors}}</span>
|
<span class="authors">Authors: {{exam.get_authors}}</span>
|
||||||
{% if exam.exam_mode %}
|
{% if exam.exam_mode %}
|
||||||
{% if app_name in "rapids longs anatomy" %}
|
{% if app_name in "rapids longs anatomy" %}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% include "generic/exam_link_headers.html" %}
|
{% include "generic/exam_link_headers.html" %}
|
||||||
<h1>Exam: {{ exam.name }}</h1>
|
<h1>Exam: {{ exam }}</h1>
|
||||||
|
|
||||||
{% include 'exam_notes.html' %}
|
{% include 'exam_notes.html' %}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="">
|
<div class="">
|
||||||
<h2>{{ exam.name }}</h2>
|
<h2>{{ exam }}</h2>
|
||||||
{% if cached_scores %}
|
{% if cached_scores %}
|
||||||
User answer scores are cached, if you update or change an answer you will need to <a href="{% url exam.app_name|add:':exam_scores_refresh' exam.pk %}">refresh the scores</a>.
|
User answer scores are cached, if you update or change an answer you will need to <a href="{% url exam.app_name|add:':exam_scores_refresh' exam.pk %}">refresh the scores</a>.
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
+3
-7
@@ -556,7 +556,7 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
data = {
|
data = {
|
||||||
"status": "success",
|
"status": "success",
|
||||||
"archive": exam.archive,
|
"archive": exam.archive,
|
||||||
"name": exam.name,
|
"name": exam,
|
||||||
"id": exam.id,
|
"id": exam.id,
|
||||||
}
|
}
|
||||||
return JsonResponse(data, status=200)
|
return JsonResponse(data, status=200)
|
||||||
@@ -580,7 +580,7 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
data = {
|
data = {
|
||||||
"status": "success",
|
"status": "success",
|
||||||
"publish_results": exam.publish_results,
|
"publish_results": exam.publish_results,
|
||||||
"name": exam.name,
|
"name": exam,
|
||||||
"id": exam.id,
|
"id": exam.id,
|
||||||
}
|
}
|
||||||
return JsonResponse(data, status=200)
|
return JsonResponse(data, status=200)
|
||||||
@@ -602,7 +602,7 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
data = {
|
data = {
|
||||||
"status": "success",
|
"status": "success",
|
||||||
"active": exam.active,
|
"active": exam.active,
|
||||||
"name": exam.name,
|
"name": exam,
|
||||||
"id": exam.id,
|
"id": exam.id,
|
||||||
}
|
}
|
||||||
return JsonResponse(data, status=200)
|
return JsonResponse(data, status=200)
|
||||||
@@ -1483,13 +1483,9 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
exam: ExamBase
|
exam: ExamBase
|
||||||
for exam in exams:
|
for exam in exams:
|
||||||
if exam.active or self.check_user_access(request.user, exam.pk):
|
if exam.active or self.check_user_access(request.user, exam.pk):
|
||||||
print(
|
|
||||||
f"{exam.app_name=}, {exam.name=}, {cid=}, {passcode=}, {request.user=}"
|
|
||||||
)
|
|
||||||
if exam.exam_mode and not exam.check_cid_user(
|
if exam.exam_mode and not exam.check_cid_user(
|
||||||
cid, passcode, user=request.user, user_id=request.user.pk
|
cid, passcode, user=request.user, user_id=request.user.pk
|
||||||
):
|
):
|
||||||
print(exam.name, "fail")
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if exam.json_creation_time:
|
if exam.json_creation_time:
|
||||||
|
|||||||
@@ -19,77 +19,3 @@
|
|||||||
{% endblock table_answers %}
|
{% endblock table_answers %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% comment %} {% extends 'longs/exams.html' %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<div class="longs">
|
|
||||||
<h2>{{ exam.name }}</h2>
|
|
||||||
|
|
||||||
{% if unmarked %}
|
|
||||||
<div class="alert alert-warning" role="alert">
|
|
||||||
The following questions need marking
|
|
||||||
{% for exam_index in unmarked %}
|
|
||||||
<a href="{% url 'longs:mark' exam.pk exam_index %}">{{ exam_index|add:1 }}</a>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div id="stats-block">
|
|
||||||
<h3>Stats</h3>
|
|
||||||
Candidates: {{cids|length}}<br />
|
|
||||||
Available marks: {{max_score}}<br />
|
|
||||||
Mean: {{mean}}, Median {{median}}, Mode {{mode}}
|
|
||||||
|
|
||||||
<div id="stats-plot">{{plot|safe}}</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<table class="table table-dark table-striped table-hover table-sm">
|
|
||||||
<tr>
|
|
||||||
<th>Candidate ID</th>
|
|
||||||
<th>Score</th>
|
|
||||||
<th>Normalised score</th>
|
|
||||||
</tr>
|
|
||||||
{% for user, value in user_answers_marks.items %}
|
|
||||||
<tr>
|
|
||||||
<td><a href="{% url 'cid_scores_admin' user %}">{{user}}</a></td>
|
|
||||||
<td>{{user_scores|get_item:user}}</td>
|
|
||||||
<td>{{user_scores_normalised|get_item:user}}</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<h3>Results as a table</h3>
|
|
||||||
<table class="longs table table-dark table-striped table-hover table-sm">
|
|
||||||
<thead class="thead-dark">
|
|
||||||
<tr>
|
|
||||||
<th>Candidate</th>
|
|
||||||
{% for cid in cids %}
|
|
||||||
<th><a href="{% url 'longs:exam_scores_cid_user' exam.pk cid 'None' %}">{{cid}}</a></th>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
{% for question in questions %}
|
|
||||||
<tr>
|
|
||||||
<td><a href="{% url 'longs:mark' exam_id=exam.pk sk=forloop.counter0 %}">Question
|
|
||||||
{{forloop.counter}}</a></td>
|
|
||||||
{% for ans, score in by_question|get_item:question %}
|
|
||||||
<td class="user-answer-score-{{score}}" title="answer score: {{score}}">{{score}}</td>
|
|
||||||
{% endfor %}
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
<tr>
|
|
||||||
<td>Score:</td>
|
|
||||||
{% for score in user_scores_list %}
|
|
||||||
<td>{{score}}</td>
|
|
||||||
{% endfor %}
|
|
||||||
<tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
{% endblock %} {% endcomment %}
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
{% block navigation %}
|
{% block navigation %}
|
||||||
{{block.super}}
|
{{block.super}}
|
||||||
<br/>
|
<br/>
|
||||||
Exams: {{exam.name}}->
|
Exams: {{exam}}->
|
||||||
<a href="{% url 'longs:exam_overview' pk=exam.pk %}">Overview</a> /
|
<a href="{% url 'longs:exam_overview' pk=exam.pk %}">Overview</a> /
|
||||||
<a href="{% url 'longs:mark_overview' pk=exam.pk %}">Mark</a> /
|
<a href="{% url 'longs:mark_overview' pk=exam.pk %}">Mark</a> /
|
||||||
<a href="{% url 'longs:exam_scores_all' pk=exam.pk %}">Scores</a> /
|
<a href="{% url 'longs:exam_scores_all' pk=exam.pk %}">Scores</a> /
|
||||||
|
|||||||
@@ -70,7 +70,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<div>
|
<div>
|
||||||
Exam(s): {% for exam in question.exams.all %}
|
Exam(s): {% for exam in question.exams.all %}
|
||||||
<a href="{% url 'longs:exam_overview' pk=exam.pk %}">{{ exam.name }}</a>,
|
<a href="{% url 'longs:exam_overview' pk=exam.pk %}">{{ exam }}</a>,
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="longs">
|
<div class="longs">
|
||||||
<h2>Marking exam: {{ exam.name }}</h2>
|
<h2>Marking exam: {{ exam }}</h2>
|
||||||
You can start marking from a particular question by clicking on it below.
|
You can start marking from a particular question by clicking on it below.
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
{% if previous > -1 %}
|
{% if previous > -1 %}
|
||||||
<a href="{% url 'longs:exam_question_detail' exam.id previous %}">Previous question</a>
|
<a href="{% url 'longs:exam_question_detail' exam.id previous %}">Previous question</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
Viewing question as part of exam: <a href="{% url 'longs:exam_overview' exam.id %}">{{exam.name}}</a> [{{pos}}/{{exam_length}}]
|
Viewing question as part of exam: <a href="{% url 'longs:exam_overview' exam.id %}">{{exam}}</a> [{{pos}}/{{exam_length}}]
|
||||||
{% if next %}
|
{% if next %}
|
||||||
<a href="{% url 'longs:exam_question_detail' exam.id next %}">Next question</a>
|
<a href="{% url 'longs:exam_question_detail' exam.id next %}">Next question</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -445,7 +445,7 @@ def test_exams(db, client):
|
|||||||
.find("li", attrs={"data-exam-id": exam.pk})
|
.find("li", attrs={"data-exam-id": exam.pk})
|
||||||
)
|
)
|
||||||
assert search_exam
|
assert search_exam
|
||||||
assert exam.name in str(search_exam)
|
assert str(exam) in str(search_exam)
|
||||||
assert len(search_exam.find("button", {"class": "start-button"})) > 0
|
assert len(search_exam.find("button", {"class": "start-button"})) > 0
|
||||||
# assert "Active" in assigned_exams # check it is active
|
# assert "Active" in assigned_exams # check it is active
|
||||||
|
|
||||||
@@ -461,8 +461,8 @@ def test_exams(db, client):
|
|||||||
.find_all("li", attrs={"data-exam-id": exam.pk})
|
.find_all("li", attrs={"data-exam-id": exam.pk})
|
||||||
)
|
)
|
||||||
assert results_exam
|
assert results_exam
|
||||||
assert exam.name in str(results_exam)
|
assert str(exam) in str(results_exam)
|
||||||
assert exam.name + " test" not in str(results_exam)
|
assert str(exam) + " test" not in str(results_exam)
|
||||||
assert "Results Published" not in str(
|
assert "Results Published" not in str(
|
||||||
results_exam
|
results_exam
|
||||||
) # It should not be published yet
|
) # It should not be published yet
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
{% for exam in exams %}
|
{% for exam in exams %}
|
||||||
{% if exam.active %}
|
{% if exam.active %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url 'physics:exam_start' pk=exam.pk %}">{{exam.name}}</a>
|
<a href="{% url 'physics:exam_start' pk=exam.pk %}">{{exam}}</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<h2>Start exam: {{exam.name}}</h2>
|
<h2>Start exam: {{exam}}</h2>
|
||||||
|
|
||||||
{% if exam.time_limit %}
|
{% if exam.time_limit %}
|
||||||
This exam has a time limit of {{ exam.get_time_limit }}. The time will start when you click the Start Exam button below.<br/>
|
This exam has a time limit of {{ exam.get_time_limit }}. The time will start when you click the Start Exam button below.<br/>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
</span>
|
</span>
|
||||||
{% include "exam_clock.html" %}
|
{% include "exam_clock.html" %}
|
||||||
<div class="no-select">
|
<div class="no-select">
|
||||||
<h2>{{exam.name}}: Question [<span id="question-number">{{pos|add:1}}</span>/<span id="exam-length">{{exam_length}}</span>]</h2>
|
<h2>{{exam}}: Question [<span id="question-number">{{pos|add:1}}</span>/<span id="exam-length">{{exam_length}}</span>]</h2>
|
||||||
{% if exam.publish_results %}
|
{% if exam.publish_results %}
|
||||||
<div class="alert alert-primary review-mode-alert" role="alert">
|
<div class="alert alert-primary review-mode-alert" role="alert">
|
||||||
Exam is in review mode. Add question feedback <a href="#" onclick="return window.create_popup_window('{% url 'feedback_create' question_type='physics' pk=question.pk %}')">here</a>.
|
Exam is in review mode. Add question feedback <a href="#" onclick="return window.create_popup_window('{% url 'feedback_create' question_type='physics' pk=question.pk %}')">here</a>.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="physics">
|
<div class="physics">
|
||||||
<h1>Exam: {{ exam.name }}</h1>
|
<h1>Exam: {{ exam }}</h1>
|
||||||
|
|
||||||
<div class="alert alert-info" role="alert">
|
<div class="alert alert-info" role="alert">
|
||||||
<details>
|
<details>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
</span>
|
</span>
|
||||||
{% include "exam_clock.html" %}
|
{% include "exam_clock.html" %}
|
||||||
|
|
||||||
<h2>Exam: {{exam.name}}</h2>
|
<h2>Exam: {{exam}}</h2>
|
||||||
|
|
||||||
{% if exam.publish_results %}
|
{% if exam.publish_results %}
|
||||||
<div class="alert alert-primary review-mode-alert" role="alert">
|
<div class="alert alert-primary review-mode-alert" role="alert">
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
{% block navigation %}
|
{% block navigation %}
|
||||||
{{block.super}}
|
{{block.super}}
|
||||||
<br/>
|
<br/>
|
||||||
Exams: {{exam.name}}-> <a href="{% url 'physics:exam_overview' pk=exam.pk %}">Overview</a> /
|
Exams: {{exam}}-> <a href="{% url 'physics:exam_overview' pk=exam.pk %}">Overview</a> /
|
||||||
<a href="{% url 'physics:exam_scores_all' pk=exam.pk %}">Scores</a> /
|
<a href="{% url 'physics:exam_scores_all' pk=exam.pk %}">Scores</a> /
|
||||||
<a href="{% url 'physics:exam_cids' exam_id=exam.pk %}">Candidates</a> /
|
<a href="{% url 'physics:exam_cids' exam_id=exam.pk %}">Candidates</a> /
|
||||||
<a href="{% url 'physics:exam_stats' exam_id=exam.pk %}">Stats</a> /
|
<a href="{% url 'physics:exam_stats' exam_id=exam.pk %}">Stats</a> /
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
{% endautoescape %}
|
{% endautoescape %}
|
||||||
<div>
|
<div>
|
||||||
Examinations: {% for exam in question.exams.all %}
|
Examinations: {% for exam in question.exams.all %}
|
||||||
<a href="{% url 'physics:exam_overview' pk=exam.pk %}">{{ exam.name }}</a>
|
<a href="{% url 'physics:exam_overview' pk=exam.pk %}">{{ exam }}</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ class ExamTester:
|
|||||||
.find("li", attrs={"data-exam-id": self.exam.pk})
|
.find("li", attrs={"data-exam-id": self.exam.pk})
|
||||||
)
|
)
|
||||||
assert search_exam
|
assert search_exam
|
||||||
assert self.exam.name in str(search_exam)
|
assert str(self.exam) in str(search_exam)
|
||||||
assert len(search_exam.find("button", {"class": "start-button"})) > 0
|
assert len(search_exam.find("button", {"class": "start-button"})) > 0
|
||||||
# assert "Active" in assigned_exams # check it is active
|
# assert "Active" in assigned_exams # check it is active
|
||||||
|
|
||||||
@@ -358,8 +358,8 @@ class ExamTester:
|
|||||||
.find_all("li", attrs={"data-exam-id": self.exam.pk})
|
.find_all("li", attrs={"data-exam-id": self.exam.pk})
|
||||||
)
|
)
|
||||||
assert results_exam
|
assert results_exam
|
||||||
assert self.exam.name in str(results_exam)
|
assert str(self.exam) in str(results_exam)
|
||||||
assert self.exam.name + " test" not in str(results_exam)
|
assert str(self.exam) + " test" not in str(results_exam)
|
||||||
assert "Results Published" not in str(
|
assert "Results Published" not in str(
|
||||||
results_exam
|
results_exam
|
||||||
) # It should not be published yet
|
) # It should not be published yet
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
{% block navigation %}
|
{% block navigation %}
|
||||||
{{block.super}}
|
{{block.super}}
|
||||||
<br/>
|
<br/>
|
||||||
Exams: {{exam.name}}->
|
Exams: {{exam}}->
|
||||||
<a href="{% url 'rapids:exam_overview' pk=exam.pk %}">Overview</a> /
|
<a href="{% url 'rapids:exam_overview' pk=exam.pk %}">Overview</a> /
|
||||||
{% if exam.exam_mode %}
|
{% if exam.exam_mode %}
|
||||||
<a href="{% url 'rapids:mark_overview' pk=exam.pk %}">Mark</a> /
|
<a href="{% url 'rapids:mark_overview' pk=exam.pk %}">Mark</a> /
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="rapids">
|
<div class="rapids">
|
||||||
<h2>Marking exam: {{ exam.name }}</h2>
|
<h2>Marking exam: {{ exam }}</h2>
|
||||||
You can start marking from a particular question by clicking on it below.
|
You can start marking from a particular question by clicking on it below.
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Exam(s): {% for exam in question.exams.all %}
|
Exam(s): {% for exam in question.exams.all %}
|
||||||
<a href="{% url 'rapids:exam_overview' pk=exam.pk %}">{{ exam.name }}</a>,
|
<a href="{% url 'rapids:exam_overview' pk=exam.pk %}">{{ exam }}</a>,
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% comment %} <button id="add-to-exam" data-exam_json_edit_url="{% url 'generic:generic_exam_json_edit' %}"
|
{% comment %} <button id="add-to-exam" data-exam_json_edit_url="{% url 'generic:generic_exam_json_edit' %}"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
{% if previous > -1 %}
|
{% if previous > -1 %}
|
||||||
<a href="{% url 'rapids:exam_question_detail' exam.id previous %}">Previous question</a>
|
<a href="{% url 'rapids:exam_question_detail' exam.id previous %}">Previous question</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
Viewing question as part of exam: <a href="{% url 'rapids:exam_overview' exam.id %}">{{exam.name}}</a> [{{pos}}/{{exam_length}}]
|
Viewing question as part of exam: <a href="{% url 'rapids:exam_overview' exam.id %}">{{exam}}</a> [{{pos}}/{{exam_length}}]
|
||||||
{% if next %}
|
{% if next %}
|
||||||
<a href="{% url 'rapids:exam_question_detail' exam.id next %}">Next question</a>
|
<a href="{% url 'rapids:exam_question_detail' exam.id next %}">Next question</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -340,7 +340,7 @@ def test_exams(db, client):
|
|||||||
.find("li", attrs={"data-exam-id": exam.pk})
|
.find("li", attrs={"data-exam-id": exam.pk})
|
||||||
)
|
)
|
||||||
assert search_exam
|
assert search_exam
|
||||||
assert exam.name in str(search_exam)
|
assert str(exam) in str(search_exam)
|
||||||
assert len(search_exam.find("button", {"class": "start-button"})) > 0
|
assert len(search_exam.find("button", {"class": "start-button"})) > 0
|
||||||
# assert "Active" in assigned_exams # check it is active
|
# assert "Active" in assigned_exams # check it is active
|
||||||
|
|
||||||
@@ -356,8 +356,8 @@ def test_exams(db, client):
|
|||||||
.find_all("li", attrs={"data-exam-id": exam.pk})
|
.find_all("li", attrs={"data-exam-id": exam.pk})
|
||||||
)
|
)
|
||||||
assert results_exam
|
assert results_exam
|
||||||
assert exam.name in str(results_exam)
|
assert str(exam) in str(results_exam)
|
||||||
assert exam.name + " test" not in str(results_exam)
|
assert str(exam) + " test" not in str(results_exam)
|
||||||
assert "Results Published" not in str(
|
assert "Results Published" not in str(
|
||||||
results_exam
|
results_exam
|
||||||
) # It should not be published yet
|
) # It should not be published yet
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
{% for exam in exams %}
|
{% for exam in exams %}
|
||||||
{% if exam.active %}
|
{% if exam.active %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url 'sbas:exam_start' pk=exam.pk %}">{{exam.name}}</a>
|
<a href="{% url 'sbas:exam_start' pk=exam.pk %}">{{exam}}</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<h2>Start exam: {{exam.name}}</h2>
|
<h2>Start exam: {{exam}}</h2>
|
||||||
|
|
||||||
{% if exam.time_limit %}
|
{% if exam.time_limit %}
|
||||||
This exam has a time limit of {{ exam.get_time_limit }}. The time will start when you click the Start Exam button below.<br/>
|
This exam has a time limit of {{ exam.get_time_limit }}. The time will start when you click the Start Exam button below.<br/>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
</span>
|
</span>
|
||||||
{% include "exam_clock.html" %}
|
{% include "exam_clock.html" %}
|
||||||
<div class="no-select">
|
<div class="no-select">
|
||||||
<h2>{{exam.name}}: Question [<span id="question-number">{{pos|add:1}}</span>/<span id="exam-length">{{exam_length}}</span>]</h2>
|
<h2>{{exam}}: Question [<span id="question-number">{{pos|add:1}}</span>/<span id="exam-length">{{exam_length}}</span>]</h2>
|
||||||
{% if exam.publish_results %}
|
{% if exam.publish_results %}
|
||||||
<div class="alert alert-primary review-mode-alert" role="alert">
|
<div class="alert alert-primary review-mode-alert" role="alert">
|
||||||
Exam is in review mode. Add question feedback <a href="#" onclick="return window.create_popup_window('{% url 'feedback_create' question_type='sbas' pk=question.pk %}')">here</a>.
|
Exam is in review mode. Add question feedback <a href="#" onclick="return window.create_popup_window('{% url 'feedback_create' question_type='sbas' pk=question.pk %}')">here</a>.
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
</span>
|
</span>
|
||||||
|
|
||||||
{% include "exam_clock.html" %}
|
{% include "exam_clock.html" %}
|
||||||
<h2>Exam: {{exam.name}}</h2>
|
<h2>Exam: {{exam}}</h2>
|
||||||
|
|
||||||
{% if exam.publish_results %}
|
{% if exam.publish_results %}
|
||||||
<div class="alert alert-primary review-mode-alert" role="alert">
|
<div class="alert alert-primary review-mode-alert" role="alert">
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
{% block navigation %}
|
{% block navigation %}
|
||||||
{{block.super}}
|
{{block.super}}
|
||||||
<br/>
|
<br/>
|
||||||
Exams: {{exam.name}}->
|
Exams: {{exam}}->
|
||||||
<a href="{% url 'sbas:exam_overview' pk=exam.pk %}">Overview</a> /
|
<a href="{% url 'sbas:exam_overview' pk=exam.pk %}">Overview</a> /
|
||||||
<a href="{% url 'sbas:exam_scores_all' pk=exam.pk %}">Scores</a> /
|
<a href="{% url 'sbas:exam_scores_all' pk=exam.pk %}">Scores</a> /
|
||||||
<a href="{% url 'sbas:exam_cids' exam_id=exam.pk %}">Candidates</a> /
|
<a href="{% url 'sbas:exam_cids' exam_id=exam.pk %}">Candidates</a> /
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
{% endautoescape %}
|
{% endautoescape %}
|
||||||
<div>
|
<div>
|
||||||
Examinations: {% for exam in question.exams.all %}
|
Examinations: {% for exam in question.exams.all %}
|
||||||
<a href="{% url 'sbas:exam_overview' pk=exam.pk %}">{{ exam.name }}</a>
|
<a href="{% url 'sbas:exam_overview' pk=exam.pk %}">{{ exam }}</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<h4>{{exam_type|title}}</h4>
|
<h4>{{exam_type|title}}</h4>
|
||||||
<ul class='{{exam_type|lower}}'>
|
<ul class='{{exam_type|lower}}'>
|
||||||
{% for exam in exams %}
|
{% for exam in exams %}
|
||||||
<li class="exam" data-exam-id="{{exam.pk}}">{{exam.name}}
|
<li class="exam" data-exam-id="{{exam.pk}}">{{exam}}
|
||||||
{% if exam.active %}
|
{% if exam.active %}
|
||||||
<a href="{{exam.get_take_url}}?cid={{cid}}&passcode={{passcode}}" target="_blank" title="Click to take exam">
|
<a href="{{exam.get_take_url}}?cid={{cid}}&passcode={{passcode}}" target="_blank" title="Click to take exam">
|
||||||
<button class="small-url-button start-button">Start</button>
|
<button class="small-url-button start-button">Start</button>
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
<h4>{{exam_type|title}}</h4>
|
<h4>{{exam_type|title}}</h4>
|
||||||
<ul class='{{exam_type|lower}}'>
|
<ul class='{{exam_type|lower}}'>
|
||||||
{% for exam in exams %}
|
{% for exam in exams %}
|
||||||
<li class="exam" data-exam-id="{{exam.pk}}"><a href="{% url exam_type|add:':exam_scores_cid_user' pk=exam.pk cid=cid passcode=passcode %}">{{exam.name}}</a> {% if exam.active %}[Active]{% endif %} {% if exam.publish_results %}[Results Published]{% endif %}</li>
|
<li class="exam" data-exam-id="{{exam.pk}}"><a href="{% url exam_type|add:':exam_scores_cid_user' pk=exam.pk cid=cid passcode=passcode %}">{{exam}}</a> {% if exam.active %}[Active]{% endif %} {% if exam.publish_results %}[Results Published]{% endif %}</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
{% load thumbnail %}
|
{% load thumbnail %}
|
||||||
<div class="{{app_name}}">
|
<div class="{{app_name}}">
|
||||||
<h1>Exam: {{ exam.name }}</h1>
|
<h1>Exam: {{ exam }}</h1>
|
||||||
|
|
||||||
{% include "generic/exam_cids.html" %}
|
{% include "generic/exam_cids.html" %}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="{{app_name}}">
|
<div class="{{app_name}}">
|
||||||
<h1>Exam: {{ exam.name }}</h1>
|
<h1>Exam: {{ exam }}</h1>
|
||||||
|
|
||||||
{% include "generic/exam_cids_edit.html" %}
|
{% include "generic/exam_cids_edit.html" %}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="">
|
<div class="">
|
||||||
<h2>{{exam.name}}</h2>
|
<h2>{{exam}}</h2>
|
||||||
Exam is currently inactive.
|
Exam is currently inactive.
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
{% for exam in exams %}
|
{% for exam in exams %}
|
||||||
{% if exam.active %}
|
{% if exam.active %}
|
||||||
<li class="exam-item">
|
<li class="exam-item">
|
||||||
<a href="{% url app_name|add:':exam_overview' pk=exam.pk %}" class="flex-col-2 exam-name">{{exam.name}}</a>
|
<a href="{% url app_name|add:':exam_overview' pk=exam.pk %}" class="flex-col-2 exam-name">{{exam}}</a>
|
||||||
{% if marking %}<a href="{% url app_name|add:':mark_overview' pk=exam.pk %}" class="flex-col-half">Mark</a>{% endif %}
|
{% if marking %}<a href="{% url app_name|add:':mark_overview' pk=exam.pk %}" class="flex-col-half">Mark</a>{% endif %}
|
||||||
<span class="flex-col">
|
<span class="flex-col">
|
||||||
<a href="{% url app_name|add:':exam_cids' exam_id=exam.pk %}">Candidates</a> <span class="candidate-counts">[<span title="Number of active CID users">
|
<a href="{% url app_name|add:':exam_cids' exam_id=exam.pk %}">Candidates</a> <span class="candidate-counts">[<span title="Number of active CID users">
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
{% for exam in exams %}
|
{% for exam in exams %}
|
||||||
{% if not exam.active %}
|
{% if not exam.active %}
|
||||||
<li class="exam-item">
|
<li class="exam-item">
|
||||||
<a href="{% url app_name|add:':exam_overview' pk=exam.pk %}" class="flex-col-2 exam-name">{{exam.name}}</a>
|
<a href="{% url app_name|add:':exam_overview' pk=exam.pk %}" class="flex-col-2 exam-name">{{exam}}</a>
|
||||||
{% if marking %}<a href="{% url app_name|add:':mark_overview' pk=exam.pk %}" class="flex-col-half">Mark</a>{% endif %}
|
{% if marking %}<a href="{% url app_name|add:':mark_overview' pk=exam.pk %}" class="flex-col-half">Mark</a>{% endif %}
|
||||||
<span class="flex-col">
|
<span class="flex-col">
|
||||||
<a href="{% url app_name|add:':exam_cids' exam_id=exam.pk %}">Candidates</a>
|
<a href="{% url app_name|add:':exam_cids' exam_id=exam.pk %}">Candidates</a>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h2>{{exam.name}}: Stats</h2>
|
<h2>{{exam}}: Stats</h2>
|
||||||
{% if exam.stats_candidates < 4 %}
|
{% if exam.stats_candidates < 4 %}
|
||||||
Not enough data points...
|
Not enough data points...
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="{{app_name}}">
|
<div class="{{app_name}}">
|
||||||
<h1>Exam: {{ exam.name }}</h1>
|
<h1>Exam: {{ exam }}</h1>
|
||||||
|
|
||||||
{% include "generic/exam_users_edit.html" %}
|
{% include "generic/exam_users_edit.html" %}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,6 @@
|
|||||||
<div class="alert alert-info" role="alert">Results are not currently published. You can see your own answers below.</a></div>
|
<div class="alert alert-info" role="alert">Results are not currently published. You can see your own answers below.</a></div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<h2>Exam: {{ exam.name }}</h2>
|
<h2>Exam: {{ exam }}</h2>
|
||||||
<h3>Candidate: {{ cid|default_if_none:request.user.username }}</h3>
|
<h3>Candidate: {{ cid|default_if_none:request.user.username }}</h3>
|
||||||
Answers:
|
Answers:
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
<h4>{{exam_type|title}}</h4>
|
<h4>{{exam_type|title}}</h4>
|
||||||
<ul class='{{exam_type|lower}}'>
|
<ul class='{{exam_type|lower}}'>
|
||||||
{% for exam in exams %}
|
{% for exam in exams %}
|
||||||
<li class="exam" data-exam-id="{{exam.pk}}">{{exam.name}}
|
<li class="exam" data-exam-id="{{exam.pk}}">{{exam}}
|
||||||
{% if exam.active %}
|
{% if exam.active %}
|
||||||
<a href="{{exam.get_take_url}}" target="_blank" title="Click to take exam">
|
<a href="{{exam.get_take_url}}" target="_blank" title="Click to take exam">
|
||||||
<button class="small-url-button start-button">Start</button>
|
<button class="small-url-button start-button">Start</button>
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
<a href= "{% url exam_type|add:':exam_scores_user' pk=exam.pk %}" title="Click to view results">
|
<a href= "{% url exam_type|add:':exam_scores_user' pk=exam.pk %}" title="Click to view results">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{{exam.name}}</a> {% if exam.active %}[Active]{% endif %} {% if exam.publish_results %}[Results Published]{% endif %}</li>
|
{{exam}}</a> {% if exam.active %}[Active]{% endif %} {% if exam.publish_results %}[Results Published]{% endif %}</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
Reference in New Issue
Block a user