improve exam collections management
This commit is contained in:
@@ -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 %}
|
||||||
@@ -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
@@ -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
@@ -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
|
||||||
|
|
||||||
@@ -100,8 +100,10 @@ def profile(request):
|
|||||||
|
|
||||||
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):
|
||||||
|
|||||||
@@ -3,9 +3,14 @@
|
|||||||
{% 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>
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,18 @@
|
|||||||
{% 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>
|
||||||
|
|
||||||
{% if rcr_assessor %}
|
{% if rcr_assessor %}
|
||||||
|
|||||||
Reference in New Issue
Block a user