From df462efacd39f43a34664229b18014c8be6f5f4d Mon Sep 17 00:00:00 2001 From: Ross Date: Mon, 8 Jul 2024 09:52:01 +0100 Subject: [PATCH] Start using start dates for exams --- anatomy/templates/anatomy/exams.html | 2 +- anatomy/templates/anatomy/mark_overview.html | 2 +- .../templates/anatomy/question_detail.html | 2 +- .../anatomy/question_link_header.html | 2 +- anatomy/tests/test_anatomy_exams.py | 6 +- atlas/models.py | 5 ++ .../atlas/collection_case_view_take.html | 2 +- .../atlas/collection_review_start.html | 2 +- atlas/templates/atlas/index.html | 2 +- atlas/views.py | 10 +++ generic/models.py | 11 ++- generic/templates/generic/exam_index.html | 2 +- .../generic/exam_overview_headers.html | 2 +- .../templates/generic/exam_scores_base.html | 2 +- generic/views.py | 10 +-- longs/templates/longs/exam_scores.html | 74 ------------------ longs/templates/longs/exams.html | 2 +- longs/templates/longs/long_display_block.html | 2 +- longs/templates/longs/mark_overview.html | 2 +- longs/templates/longs/question_detail.html | 2 +- longs/tests/test_longs_exams.py | 6 +- .../physics/available_exam_list.html | 2 +- physics/templates/physics/exam_start.html | 2 +- physics/templates/physics/exam_take.html | 2 +- physics/templates/physics/exam_take_old.html | 2 +- .../templates/physics/exam_take_overview.html | 2 +- physics/templates/physics/exams.html | 2 +- .../templates/physics/question_detail.html | 2 +- rad/tests/test_helpers.py | 6 +- rapids/templates/rapids/exams.html | 2 +- rapids/templates/rapids/mark_overview.html | 38 +++++----- .../rapids/question_display_block.html | 2 +- .../rapids/question_link_header.html | 44 +++++------ rapids/tests/test_rapids_exams.py | 6 +- sbas/templates/sbas/available_exam_list.html | 26 +++---- sbas/templates/sbas/exam_start.html | 72 +++++++++--------- sbas/templates/sbas/exam_take.html | 22 +++--- sbas/templates/sbas/exam_take_overview.html | 20 ++--- sbas/templates/sbas/exams.html | 2 +- sbas/templates/sbas/question_detail.html | 76 +++++++++---------- templates/cid_scores.html | 4 +- templates/exam_cids.html | 4 +- templates/exam_cids_edit.html | 4 +- templates/exam_inactive.html | 8 +- templates/exam_list.html | 4 +- templates/exam_stats.html | 2 +- templates/exam_users_edit.html | 4 +- templates/user_score_header.html | 14 ++-- templates/user_scores.html | 4 +- 49 files changed, 235 insertions(+), 293 deletions(-) diff --git a/anatomy/templates/anatomy/exams.html b/anatomy/templates/anatomy/exams.html index ebf76f9a..28d46ee3 100644 --- a/anatomy/templates/anatomy/exams.html +++ b/anatomy/templates/anatomy/exams.html @@ -3,7 +3,7 @@ {% block navigation %} {{block.super}}
- Exams: {{exam.name}}-> + Exams: {{exam}}-> Overview / {% if exam.exam_mode %} Mark / diff --git a/anatomy/templates/anatomy/mark_overview.html b/anatomy/templates/anatomy/mark_overview.html index 54cadabb..6141898b 100644 --- a/anatomy/templates/anatomy/mark_overview.html +++ b/anatomy/templates/anatomy/mark_overview.html @@ -2,7 +2,7 @@ {% block content %}
-

Marking exam: {{ exam.name }}

+

Marking exam: {{ exam }}

You can start marking from a particular question by clicking on it below.
diff --git a/anatomy/templates/anatomy/question_detail.html b/anatomy/templates/anatomy/question_detail.html index 8a024da3..a2f3e72a 100644 --- a/anatomy/templates/anatomy/question_detail.html +++ b/anatomy/templates/anatomy/question_detail.html @@ -45,7 +45,7 @@
Exams: {% for exam in question.exams.all %} - {{ exam.name }} + {{ exam }} {% endfor %}
diff --git a/anatomy/templates/anatomy/question_link_header.html b/anatomy/templates/anatomy/question_link_header.html index 3acacc48..aeb03c6e 100644 --- a/anatomy/templates/anatomy/question_link_header.html +++ b/anatomy/templates/anatomy/question_link_header.html @@ -19,7 +19,7 @@ {% if previous > -1 %} Previous question {% endif %} - Viewing question as part of exam: {{exam.name}} [{{pos}}/{{exam_length}}] + Viewing question as part of exam: {{exam}} [{{pos}}/{{exam_length}}] {% if next %} Next question {% endif %} diff --git a/anatomy/tests/test_anatomy_exams.py b/anatomy/tests/test_anatomy_exams.py index d1cb6c31..44ecf67a 100644 --- a/anatomy/tests/test_anatomy_exams.py +++ b/anatomy/tests/test_anatomy_exams.py @@ -303,7 +303,7 @@ def test_exams(db, client): .find("li", attrs={"data-exam-id": exam.pk}) ) 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 "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}) ) assert results_exam - assert exam.name in str(results_exam) - assert exam.name + " test" not in str(results_exam) + assert str(exam) in str(results_exam) + assert str(exam) + " test" not in str(results_exam) assert "Results Published" not in str( results_exam ) # It should not be published yet diff --git a/atlas/models.py b/atlas/models.py index 6cdde5fb..b9c76a07 100644 --- a/atlas/models.py +++ b/atlas/models.py @@ -47,6 +47,7 @@ from generic.models import ( CidUserExam, CidUserGroup, ExamOrCollectionGenericBase, + ExamUserStatus, Examination, # Condition, ExamBase, @@ -775,6 +776,8 @@ class CaseCollection(ExamOrCollectionGenericBase): 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.") class COLLECTION_TYPE_CHOICES(models.TextChoices): @@ -996,6 +999,8 @@ class CaseDetail(models.Model): question_schema = 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) diff --git a/atlas/templates/atlas/collection_case_view_take.html b/atlas/templates/atlas/collection_case_view_take.html index 22b240d6..2414487d 100644 --- a/atlas/templates/atlas/collection_case_view_take.html +++ b/atlas/templates/atlas/collection_case_view_take.html @@ -177,7 +177,7 @@ {% endif %}
-
View questions +
View questions {{form.json.errors}}
diff --git a/atlas/templates/atlas/collection_review_start.html b/atlas/templates/atlas/collection_review_start.html index fe037945..8e7d69ff 100644 --- a/atlas/templates/atlas/collection_review_start.html +++ b/atlas/templates/atlas/collection_review_start.html @@ -1,7 +1,7 @@ {% extends 'atlas/base.html' %} {% block content %} -

Collection: {{exam.name}}

+

Collection: {{exam}}

{% comment %}
    {% for case in collection.cases.all %} diff --git a/atlas/templates/atlas/index.html b/atlas/templates/atlas/index.html index a66602e8..0ed34a86 100644 --- a/atlas/templates/atlas/index.html +++ b/atlas/templates/atlas/index.html @@ -9,6 +9,6 @@

    My cases / collections

    View my cases.
    - + Uploads awaiting import {% endblock %} \ No newline at end of file diff --git a/atlas/views.py b/atlas/views.py index 8d038462..df2a5bb6 100755 --- a/atlas/views.py +++ b/atlas/views.py @@ -1914,6 +1914,16 @@ def collection_take_overview( cid_user_exam.completed = True 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") else: raise Http404() diff --git a/generic/models.py b/generic/models.py index b6e9f66e..c6a685cf 100644 --- a/generic/models.py +++ b/generic/models.py @@ -869,6 +869,14 @@ class ExamBase(ExamOrCollectionGenericBase): class Meta: 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): self.recreate_json = recreate_json @@ -903,9 +911,6 @@ class ExamBase(ExamOrCollectionGenericBase): """ return text - def __str__(self): - return self.name - def get_absolute_url(self): return reverse("{}:exam_overview".format(self.app_name), kwargs={"pk": self.pk}) diff --git a/generic/templates/generic/exam_index.html b/generic/templates/generic/exam_index.html index 7d2f6f05..3f1a4789 100644 --- a/generic/templates/generic/exam_index.html +++ b/generic/templates/generic/exam_index.html @@ -20,7 +20,7 @@ {% else %} Packet: {% endif %} - {{ exam.name }} + {{ exam }} Authors: {{exam.get_authors}} {% if exam.exam_mode %} {% if app_name in "rapids longs anatomy" %} diff --git a/generic/templates/generic/exam_overview_headers.html b/generic/templates/generic/exam_overview_headers.html index 2ef494ec..602de13c 100644 --- a/generic/templates/generic/exam_overview_headers.html +++ b/generic/templates/generic/exam_overview_headers.html @@ -1,5 +1,5 @@ {% include "generic/exam_link_headers.html" %} -

    Exam: {{ exam.name }}

    +

    Exam: {{ exam }}

    {% include 'exam_notes.html' %} diff --git a/generic/templates/generic/exam_scores_base.html b/generic/templates/generic/exam_scores_base.html index 753c003f..a7a25559 100644 --- a/generic/templates/generic/exam_scores_base.html +++ b/generic/templates/generic/exam_scores_base.html @@ -2,7 +2,7 @@ {% block content %}
    -

    {{ exam.name }}

    +

    {{ exam }}

    {% if cached_scores %} User answer scores are cached, if you update or change an answer you will need to refresh the scores. {% endif %} diff --git a/generic/views.py b/generic/views.py index b1ebb901..87165676 100644 --- a/generic/views.py +++ b/generic/views.py @@ -556,7 +556,7 @@ class ExamViews(View, LoginRequiredMixin): data = { "status": "success", "archive": exam.archive, - "name": exam.name, + "name": exam, "id": exam.id, } return JsonResponse(data, status=200) @@ -580,7 +580,7 @@ class ExamViews(View, LoginRequiredMixin): data = { "status": "success", "publish_results": exam.publish_results, - "name": exam.name, + "name": exam, "id": exam.id, } return JsonResponse(data, status=200) @@ -602,7 +602,7 @@ class ExamViews(View, LoginRequiredMixin): data = { "status": "success", "active": exam.active, - "name": exam.name, + "name": exam, "id": exam.id, } return JsonResponse(data, status=200) @@ -1483,13 +1483,9 @@ class ExamViews(View, LoginRequiredMixin): exam: ExamBase for exam in exams: 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( cid, passcode, user=request.user, user_id=request.user.pk ): - print(exam.name, "fail") continue if exam.json_creation_time: diff --git a/longs/templates/longs/exam_scores.html b/longs/templates/longs/exam_scores.html index 233c5033..b389e1d7 100644 --- a/longs/templates/longs/exam_scores.html +++ b/longs/templates/longs/exam_scores.html @@ -19,77 +19,3 @@ {% endblock table_answers %} - - -{% comment %} {% extends 'longs/exams.html' %} - -{% block content %} -
    -

    {{ exam.name }}

    - - {% if unmarked %} - - - {% endif %} - -
    -
    -

    Stats

    - Candidates: {{cids|length}}
    - Available marks: {{max_score}}
    - Mean: {{mean}}, Median {{median}}, Mode {{mode}} - -
    {{plot|safe}}
    -
    -
    - - - - - - - {% for user, value in user_answers_marks.items %} - - - - - - {% endfor %} -
    Candidate IDScoreNormalised score
    {{user}}{{user_scores|get_item:user}}{{user_scores_normalised|get_item:user}}
    -
    -
    -

    Results as a table

    - - - - - {% for cid in cids %} - - {% endfor %} - - - - {% for question in questions %} - - - {% for ans, score in by_question|get_item:question %} - - {% endfor %} - - {% endfor %} - - - {% for score in user_scores_list %} - - {% endfor %} - -
    Candidate{{cid}}
    Question - {{forloop.counter}}{{score}}
    Score:{{score}}
    - -
    -{% endblock %} {% endcomment %} \ No newline at end of file diff --git a/longs/templates/longs/exams.html b/longs/templates/longs/exams.html index c892d469..2c8d208d 100644 --- a/longs/templates/longs/exams.html +++ b/longs/templates/longs/exams.html @@ -3,7 +3,7 @@ {% block navigation %} {{block.super}}
    - Exams: {{exam.name}}-> + Exams: {{exam}}-> Overview / Mark / Scores / diff --git a/longs/templates/longs/long_display_block.html b/longs/templates/longs/long_display_block.html index df211522..7d62af16 100755 --- a/longs/templates/longs/long_display_block.html +++ b/longs/templates/longs/long_display_block.html @@ -70,7 +70,7 @@

    Exam(s): {% for exam in question.exams.all %} - {{ exam.name }}, + {{ exam }}, {% endfor %}
    diff --git a/longs/templates/longs/mark_overview.html b/longs/templates/longs/mark_overview.html index d366981c..05c0d706 100644 --- a/longs/templates/longs/mark_overview.html +++ b/longs/templates/longs/mark_overview.html @@ -2,7 +2,7 @@ {% block content %}
    -

    Marking exam: {{ exam.name }}

    +

    Marking exam: {{ exam }}

    You can start marking from a particular question by clicking on it below.
    diff --git a/longs/templates/longs/question_detail.html b/longs/templates/longs/question_detail.html index 9b069af9..d57a8990 100755 --- a/longs/templates/longs/question_detail.html +++ b/longs/templates/longs/question_detail.html @@ -18,7 +18,7 @@ {% if previous > -1 %} Previous question {% endif %} - Viewing question as part of exam: {{exam.name}} [{{pos}}/{{exam_length}}] + Viewing question as part of exam: {{exam}} [{{pos}}/{{exam_length}}] {% if next %} Next question {% endif %} diff --git a/longs/tests/test_longs_exams.py b/longs/tests/test_longs_exams.py index fa9ccd24..1d719675 100644 --- a/longs/tests/test_longs_exams.py +++ b/longs/tests/test_longs_exams.py @@ -445,7 +445,7 @@ def test_exams(db, client): .find("li", attrs={"data-exam-id": exam.pk}) ) 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 "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}) ) assert results_exam - assert exam.name in str(results_exam) - assert exam.name + " test" not in str(results_exam) + assert str(exam) in str(results_exam) + assert str(exam) + " test" not in str(results_exam) assert "Results Published" not in str( results_exam ) # It should not be published yet diff --git a/physics/templates/physics/available_exam_list.html b/physics/templates/physics/available_exam_list.html index 23b2405c..43e7f380 100644 --- a/physics/templates/physics/available_exam_list.html +++ b/physics/templates/physics/available_exam_list.html @@ -8,7 +8,7 @@ {% for exam in exams %} {% if exam.active %}
  • - {{exam.name}} + {{exam}}
  • {% endif %} {% endfor %} diff --git a/physics/templates/physics/exam_start.html b/physics/templates/physics/exam_start.html index c21171b1..ed5d6df2 100755 --- a/physics/templates/physics/exam_start.html +++ b/physics/templates/physics/exam_start.html @@ -2,7 +2,7 @@ {% block content %} -

    Start exam: {{exam.name}}

    +

    Start exam: {{exam}}

    {% 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.
    diff --git a/physics/templates/physics/exam_take.html b/physics/templates/physics/exam_take.html index c466db2a..e9e9454b 100755 --- a/physics/templates/physics/exam_take.html +++ b/physics/templates/physics/exam_take.html @@ -10,7 +10,7 @@ {% include "exam_clock.html" %}
    -

    {{exam.name}}: Question [{{pos|add:1}}/{{exam_length}}]

    +

    {{exam}}: Question [{{pos|add:1}}/{{exam_length}}]

    {% if exam.publish_results %}