From 9a5088c03aa41bd047f20cc39d13b1148468c13a Mon Sep 17 00:00:00 2001 From: Ross Date: Mon, 10 Jul 2023 09:06:46 +0100 Subject: [PATCH] start adding self review to collections --- .../0004_casecollection_self_review.py | 18 ++++++++++++++++++ atlas/models.py | 15 +++++++++------ .../atlas/collection_take_overview.html | 2 ++ atlas/views.py | 14 +++++++++----- .../migrations/0005_ciduserexam_completed.py | 18 ++++++++++++++++++ .../0006_alter_ciduserexam_completed.py | 18 ++++++++++++++++++ generic/models.py | 5 +++++ 7 files changed, 79 insertions(+), 11 deletions(-) create mode 100644 atlas/migrations/0004_casecollection_self_review.py create mode 100644 generic/migrations/0005_ciduserexam_completed.py create mode 100644 generic/migrations/0006_alter_ciduserexam_completed.py diff --git a/atlas/migrations/0004_casecollection_self_review.py b/atlas/migrations/0004_casecollection_self_review.py new file mode 100644 index 00000000..c58a3fdd --- /dev/null +++ b/atlas/migrations/0004_casecollection_self_review.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.4 on 2023-07-03 12:52 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('atlas', '0003_alter_series_modality'), + ] + + operations = [ + migrations.AddField( + model_name='casecollection', + name='self_review', + field=models.BooleanField(default=False, help_text='If true allows users self complete and review cases in a self directed way.'), + ), + ] diff --git a/atlas/models.py b/atlas/models.py index 1b2e835a..280856f3 100644 --- a/atlas/models.py +++ b/atlas/models.py @@ -329,7 +329,6 @@ class SeriesImage(SeriesImageBase): ) - class SeriesFinding(models.Model): series = models.ForeignKey( "Series", related_name="findings", on_delete=models.SET_NULL, null=True @@ -400,13 +399,13 @@ class Series(SeriesBase): self.pk, self.get_examination_full(), self.description, case_id ) - def get_absolute_url(self): return reverse("atlas:series_detail", kwargs={"pk": self.pk}) def get_link(self): - return format_html("{}", self.get_absolute_url(), self.get_full_str()) - + return format_html( + "{}", self.get_absolute_url(), self.get_full_str() + ) class CaseCollection(ExamCollectionGenericBase): @@ -476,6 +475,12 @@ class CaseCollection(ExamCollectionGenericBase): archive = models.BooleanField(default=False) exam_mode = models.BooleanField(default=False) + # This should override the publish setting + self_review = models.BooleanField( + default=False, + help_text="If true allows users self complete and review cases in a self directed way.", + ) + open_access = models.BooleanField( help_text="If the exam is freely accessible (to view and edit on the test system)", default=False, @@ -550,8 +555,6 @@ class BaseReportAnswer(models.Model): else: raise ValueError("No cid or user specified") - - class Meta: abstract = True diff --git a/atlas/templates/atlas/collection_take_overview.html b/atlas/templates/atlas/collection_take_overview.html index e4815f97..3fedce45 100644 --- a/atlas/templates/atlas/collection_take_overview.html +++ b/atlas/templates/atlas/collection_take_overview.html @@ -31,6 +31,8 @@ Start time: {{cid_user_exam.start_time}} +

Completed: {{cid_user_exam.completed}}

+ {% endblock %} {% block js %} diff --git a/atlas/views.py b/atlas/views.py index 9cc98442..e14a60f4 100755 --- a/atlas/views.py +++ b/atlas/views.py @@ -1255,7 +1255,7 @@ def collection_take_overview( ): collection = get_object_or_404(CaseCollection, pk=pk) - if not collection.active: + if not collection.active and not collection.self_review: raise Http404("Exam not found") if not collection.check_cid_user(cid, passcode, request): @@ -1268,7 +1268,9 @@ def collection_take_overview( if cid is not None: answers = CidReportAnswer.objects.filter(cid=cid, question__in=case_details) else: - answers = UserReportAnswer.objects.filter(user=request.user, question__in=case_details) + answers = UserReportAnswer.objects.filter( + user=request.user, question__in=case_details + ) answer_question_map = {} for ans in answers: @@ -1283,7 +1285,9 @@ def collection_take_overview( else: question_answer_tuples.append((q, None)) - cid_user_exam = collection.get_or_create_cid_user_exam(cid=cid, user_user=request.user) + cid_user_exam = collection.get_or_create_cid_user_exam( + cid=cid, user_user=request.user + ) return render( request, @@ -1317,7 +1321,7 @@ def collection_case_view_take( answer: CidReportAnswer | UserReportAnswer if collection.collection_type != collection.COLLECTION_TYPE_CHOICES.REVIEW: - if not collection.active: + if not collection.active and not collection.self_review: raise Http404("Exam not found") if cid is not None and not collection.check_cid_user(cid, passcode, request): @@ -1439,7 +1443,7 @@ def collection_case_view(request, pk, case_number): answer = None if collection.collection_type != collection.COLLECTION_TYPE_CHOICES.REVIEW: - if not collection.active: + if not collection.active and not collection.self_review: raise Http404("Exam not found") cases = collection.cases.all().order_by("casedetail__sort_order").prefetch_related() diff --git a/generic/migrations/0005_ciduserexam_completed.py b/generic/migrations/0005_ciduserexam_completed.py new file mode 100644 index 00000000..126faf87 --- /dev/null +++ b/generic/migrations/0005_ciduserexam_completed.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.4 on 2023-07-03 12:47 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('generic', '0004_examination_modality'), + ] + + operations = [ + migrations.AddField( + model_name='ciduserexam', + name='completed', + field=models.BooleanField(default=False, help_text='If a exam has be completed. This will usually lock the exam to further reponses.'), + ), + ] diff --git a/generic/migrations/0006_alter_ciduserexam_completed.py b/generic/migrations/0006_alter_ciduserexam_completed.py new file mode 100644 index 00000000..4741a2e0 --- /dev/null +++ b/generic/migrations/0006_alter_ciduserexam_completed.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.4 on 2023-07-03 12:50 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('generic', '0005_ciduserexam_completed'), + ] + + operations = [ + migrations.AlterField( + model_name='ciduserexam', + name='completed', + field=models.BooleanField(default=False, help_text='If a exam has been completed. This will usually lock the exam to further reponses.'), + ), + ] diff --git a/generic/models.py b/generic/models.py index 8f186166..0a028a49 100644 --- a/generic/models.py +++ b/generic/models.py @@ -1044,6 +1044,11 @@ class CidUserExam(models.Model): start_time = models.DateTimeField(blank=True, null=True) end_time = models.DateTimeField(blank=True, null=True) + completed = models.BooleanField( + default=False, + help_text="If a exam has been completed. This will usually lock the exam to further reponses.", + ) + cid_user = models.ForeignKey( CidUser, on_delete=models.CASCADE,