improve exam collections management

This commit is contained in:
Ross
2024-12-16 11:53:22 +00:00
parent 4476d0b55f
commit 92f9cabcc0
7 changed files with 58 additions and 20 deletions
@@ -19,6 +19,7 @@ This collection contains the following exams
<li><a href="{% url 'anatomy:exam_overview' exam.pk %}">{{ exam }}</a> - <a href="{% url 'anatomy:exam_update' exam.pk %}">(Edit)</a></li> <li><a href="{% url 'anatomy:exam_overview' exam.pk %}">{{ exam }}</a> - <a href="{% url 'anatomy:exam_update' exam.pk %}">(Edit)</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
<a href="{% url 'anatomy:exam_list_collection' object.pk %}">View exam list</a>
<h2>Longs Exams:</h2> <h2>Longs Exams:</h2>
<ul> <ul>
@@ -26,6 +27,7 @@ This collection contains the following exams
<li><a href="{% url 'longs:exam_overview' exam.pk %}">{{ exam }}</a> - <a href="{% url 'longs:exam_update' exam.pk %}">(Edit)</a></li> <li><a href="{% url 'longs:exam_overview' exam.pk %}">{{ exam }}</a> - <a href="{% url 'longs:exam_update' exam.pk %}">(Edit)</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
<a href="{% url 'longs:exam_list_collection' object.pk %}">View exam list</a>
<h2>Rapids Exams:</h2> <h2>Rapids Exams:</h2>
<ul> <ul>
@@ -33,6 +35,7 @@ This collection contains the following exams
<li><a href="{% url 'rapids:exam_overview' exam.pk %}">{{ exam }}</a> - <a href="{% url 'rapids:exam_update' exam.pk %}">(Edit)</a></li> <li><a href="{% url 'rapids:exam_overview' exam.pk %}">{{ exam }}</a> - <a href="{% url 'rapids:exam_update' exam.pk %}">(Edit)</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
<a href="{% url 'rapids:exam_list_collection' object.pk %}">View exam list</a>
<h2>Physics Exams:</h2> <h2>Physics Exams:</h2>
<ul> <ul>
@@ -40,6 +43,7 @@ This collection contains the following exams
<li><a href="{% url 'physics:exam_overview' exam.pk %}">{{ exam }}</a> - <a href="{% url 'physics:exam_update' exam.pk %}">(Edit)</a></li> <li><a href="{% url 'physics:exam_overview' exam.pk %}">{{ exam }}</a> - <a href="{% url 'physics:exam_update' exam.pk %}">(Edit)</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
<a href="{% url 'physics:exam_list_collection' object.pk %}">View exam list</a>
<h2>SBAs Exams:</h2> <h2>SBAs Exams:</h2>
<ul> <ul>
@@ -47,6 +51,7 @@ This collection contains the following exams
<li><a href="{% url 'sbas:exam_overview' exam.pk %}">{{ exam }}</a> - <a href="{% url 'sbas:exam_update' exam.pk %}">(Edit)</a></li> <li><a href="{% url 'sbas:exam_overview' exam.pk %}">{{ exam }}</a> - <a href="{% url 'sbas:exam_update' exam.pk %}">(Edit)</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
<a href="{% url 'sbas:exam_list_collection' object.pk %}">View exam list</a>
@@ -20,7 +20,7 @@
<h2>Edit Exam Collection {{object.name}}</h2> <h2>Edit Exam Collection {{object.name}}</h2>
<form action="" method="post" enctype="multipart/form-data" id="examcollection-form"> <form action="" method="post" enctype="multipart/form-data" id="examcollection-form">
{% csrf_token %} {% csrf_token %}
{{ form|crispy }} {{ form|crispy }}
<input type="submit" class="submit-button" value="Submit" name="submit"> <input type="submit" class="submit-button" value="Submit" name="submit">
</form> </form>
{% endblock %} {% endblock %}
+1
View File
@@ -396,6 +396,7 @@ def generic_exam_urls(generic_exam_view: GenericExamViews):
name="exam_answers_submit", name="exam_answers_submit",
), ),
path("exam/", generic_exam_view.exam_list, name="exam_list"), path("exam/", generic_exam_view.exam_list, name="exam_list"),
path("exam/<int:collection_id>/collection", generic_exam_view.exam_list_collection, name="exam_list_collection"),
path("exam/all", generic_exam_view.exam_list_all, name="exam_list_all"), path("exam/all", generic_exam_view.exam_list_all, name="exam_list_all"),
path( path(
"exam/<int:exam_id>/order_questions", "exam/<int:exam_id>/order_questions",
+29 -16
View File
@@ -759,24 +759,36 @@ class ExamViews(View, LoginRequiredMixin):
return HttpResponse("Done") return HttpResponse("Done")
@method_decorator(login_required) @method_decorator(login_required)
def exam_list(self, request, all=False): def exam_list_collection(self, request, collection_id):
if not self.check_user_access(request.user): collection = get_object_or_404(ExamCollection, pk=collection_id)
# raise PermissionDenied
exam_list = self.Exam.objects.filter(
author__id=request.user.id, exam_mode=True
).order_by("name")
exam_list = exam_list | self.Exam.objects.filter( if not request.user in collection.author.all():
markers__id=request.user.id, exam_mode=True raise PermissionDenied
).order_by("name")
else: return self.exam_list(request, all=True, collection=collection)
exam_list = (
self.Exam.objects.prefetch_related( @method_decorator(login_required)
"valid_user_users", "valid_cid_users" def exam_list(self, request, all=False, collection=None):
if collection is None:
if not self.check_user_access(request.user):
# raise PermissionDenied
exam_list = self.Exam.objects.filter(
author__id=request.user.id, exam_mode=True
).order_by("name")
exam_list = exam_list | self.Exam.objects.filter(
markers__id=request.user.id, exam_mode=True
).order_by("name")
else:
exam_list = (
self.Exam.objects.prefetch_related(
"valid_user_users", "valid_cid_users"
)
.filter(exam_mode=True)
.order_by("name")
) )
.filter(exam_mode=True) else:
.order_by("name") exam_list = self.Exam.objects.filter(exam_mode=True, examcollection__in=[collection]).order_by("name")
)
if not all: if not all:
exam_list = exam_list.filter(archive=False).order_by("name") exam_list = exam_list.filter(archive=False).order_by("name")
@@ -794,6 +806,7 @@ class ExamViews(View, LoginRequiredMixin):
"app_name": self.app_name, "app_name": self.app_name,
"view_all": all, "view_all": all,
"marking": marking, "marking": marking,
"collection": collection,
}, },
) )
+4 -2
View File
@@ -65,7 +65,7 @@ from rapids.views import GenericExamViews as RapidsExamsViews
from longs.views import GenericExamViews as LongsExamViews from longs.views import GenericExamViews as LongsExamViews
from generic.forms import QuestionNoteForm from generic.forms import QuestionNoteForm
from generic.models import CidUser, QuestionNote, Supervisor, UserGrades, UserProfile from generic.models import CidUser, ExamCollection, QuestionNote, Supervisor, UserGrades, UserProfile
from django_filters.views import FilterView from django_filters.views import FilterView
@@ -99,9 +99,11 @@ def profile(request):
return render(request, "profile.html", {"user": user}) return render(request, "profile.html", {"user": user})
def index(request): def index(request):
collections = ExamCollection.objects.filter(archive=False, author=request.user)
rcr_assessor = request.user.groups.filter(Q(name="rcr_radiology_assessor") | Q(name="rcr_oncology_assessor")| Q(name="rcr_assessor")).exists() rcr_assessor = request.user.groups.filter(Q(name="rcr_radiology_assessor") | Q(name="rcr_oncology_assessor")| Q(name="rcr_assessor")).exists()
return render(request, "index.html", {"rcr_assessor": rcr_assessor}) return render(request, "index.html", {"rcr_assessor": rcr_assessor, "collections": collections})
@user_is_cid_user_manager @user_is_cid_user_manager
def account_profile(request, slug): def account_profile(request, slug):
+6 -1
View File
@@ -2,10 +2,15 @@
{% block content %} {% block content %}
<h1>Examinations</h1> <h1>Examinations</h1>
{% if collection %}
<h2>Collection: {{collection.name}}</h2>
{% endif %}
<details class="help-text"> <details class="help-text">
<summary><i class="bi bi-info-circle"></i> Help</summary> <summary><i class="bi bi-info-circle"></i> Help</summary>
<p>This page shows the currently active examations (that you have access to manage).</p> <p>This page shows the currently active examinations (that you have access to manage).</p>
<p>Exams that are active will be available for candidates to take.</p> <p>Exams that are active will be available for candidates to take.</p>
+12
View File
@@ -42,6 +42,18 @@
</p> </p>
{% endif %} {% endif %}
{% if collections %}
<h2>Exam collections</h2>
<ul>
{% for collection in collections %}
<li><a href="{% url 'generic:examcollection_detail' collection.pk %}">{{collection.name}}</a></li>
{% endfor %}
</ul>
{% endif %}
<p><a href="http://www.penracourses.org.uk/rts">RTS is available here</a></p> <p><a href="http://www.penracourses.org.uk/rts">RTS is available here</a></p>