allow adding users to exams by group
This commit is contained in:
+13
-9
@@ -68,6 +68,7 @@ from django.forms.utils import from_current_timezone, to_current_timezone
|
|||||||
from crispy_forms.helper import FormHelper
|
from crispy_forms.helper import FormHelper
|
||||||
from crispy_forms.layout import Submit
|
from crispy_forms.layout import Submit
|
||||||
|
|
||||||
|
|
||||||
class SplitDateTimeFieldDefaultTime(SplitDateTimeField):
|
class SplitDateTimeFieldDefaultTime(SplitDateTimeField):
|
||||||
def compress(self, data_list):
|
def compress(self, data_list):
|
||||||
if data_list:
|
if data_list:
|
||||||
@@ -111,13 +112,12 @@ class ExamFormMixin:
|
|||||||
super(ModelForm, self).__init__(*args, **kwargs)
|
super(ModelForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
self.helper = FormHelper()
|
self.helper = FormHelper()
|
||||||
self.helper.form_id = 'id-exam-form'
|
self.helper.form_id = "id-exam-form"
|
||||||
self.helper.form_class = 'exam-form'
|
self.helper.form_class = "exam-form"
|
||||||
self.helper.form_method = 'post'
|
self.helper.form_method = "post"
|
||||||
self.helper.form_action = 'submit'
|
self.helper.form_action = "submit"
|
||||||
|
|
||||||
|
self.helper.add_input(Submit("submit", "Submit"))
|
||||||
self.helper.add_input(Submit('submit', 'Submit'))
|
|
||||||
|
|
||||||
# if user.is_superuser or user.groups.filter(name="cid_user_manager").exists():
|
# if user.is_superuser or user.groups.filter(name="cid_user_manager").exists():
|
||||||
# cid_user_group_queryset = CidUserGroup.objects.filter(archive=False)
|
# cid_user_group_queryset = CidUserGroup.objects.filter(archive=False)
|
||||||
@@ -199,6 +199,7 @@ class ExamAuthorFormMixin(ModelForm):
|
|||||||
widget=FilteredSelectMultiple(verbose_name="Authors", is_stacked=False),
|
widget=FilteredSelectMultiple(verbose_name="Authors", is_stacked=False),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ExamMarkerFormMixin(ModelForm):
|
class ExamMarkerFormMixin(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
fields = ["markers"]
|
fields = ["markers"]
|
||||||
@@ -227,8 +228,12 @@ class ExamGroupsFormMixin(ModelForm):
|
|||||||
cid_user_group_queryset = CidUserGroup.objects.filter(archive=False)
|
cid_user_group_queryset = CidUserGroup.objects.filter(archive=False)
|
||||||
user_user_group_queryset = UserUserGroup.objects.filter(archive=False)
|
user_user_group_queryset = UserUserGroup.objects.filter(archive=False)
|
||||||
else:
|
else:
|
||||||
cid_user_group_queryset = CidUserGroup.objects.filter(archive=False, open_access=True)
|
cid_user_group_queryset = CidUserGroup.objects.filter(
|
||||||
user_user_group_queryset = UserUserGroup.objects.none(archive=False, open_access=True)
|
archive=False, open_access=True
|
||||||
|
)
|
||||||
|
user_user_group_queryset = UserUserGroup.objects.none(
|
||||||
|
archive=False, open_access=True
|
||||||
|
)
|
||||||
# cid_user_group_queryset = CidUserGroup.objects.none()
|
# cid_user_group_queryset = CidUserGroup.objects.none()
|
||||||
# user_user_group_queryset = UserUserGroup.objects.none()
|
# user_user_group_queryset = UserUserGroup.objects.none()
|
||||||
|
|
||||||
@@ -751,4 +756,3 @@ class ExamCollectionCloneForm(ModelForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = ExamCollection
|
model = ExamCollection
|
||||||
fields = ("name", "date")
|
fields = ("name", "date")
|
||||||
|
|
||||||
|
|||||||
@@ -39,44 +39,67 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<h3>Exams</h3>
|
<h3>Exams</h3>
|
||||||
The group is currently associated with the following exams.
|
The group is currently associated with the following exams. This allows the users within the group to be easily added to the exam. It will not automatically give members of the group access to the exam.
|
||||||
{% if group_type == "cid" %}
|
{% if group_type == "cid" %}
|
||||||
Add more <a href='{% url "generic:cid_group_exams" group.pk %}'>here</a>.
|
Add more <a href='{% url "generic:cid_group_exams" group.pk %}'>here</a>.
|
||||||
{% else %}
|
{% else %}
|
||||||
Add more <a href='{% url "generic:user_group_exams" group.pk %}'>here</a>.
|
Add more <a href='{% url "generic:user_group_exams" group.pk %}'>here</a>.
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<p>It is possible to quickly add or remove all group candidates from an exam by clicking the buttons below. This will only affect the <b>{{users|length}}</b> candidates in this group. You will need to refresh the page to see updated candidate counts.</p>
|
||||||
{% with group.GetGroupExams as exam_map %}
|
{% with group.GetGroupExams as exam_map %}
|
||||||
{% for key, value in exam_map.items %}
|
{% for key, value in exam_map.items %}
|
||||||
<h4>{{key}}</h4>
|
<h4>{{key}}</h4>
|
||||||
<ul>
|
<div>
|
||||||
{% for exam in value %}
|
{% for exam in value %}
|
||||||
<li>
|
<div class="d-flex">
|
||||||
<a href="{{exam.get_absolute_url}}">{{exam}}</a>
|
<a href="{{exam.get_absolute_url}}" class="px-2">{{exam}}</a>
|
||||||
{% if group_type == "cid" %}
|
{% if group_type == "cid" %}
|
||||||
<a href="{{exam.get_cid_edit_url}}" class="edit-link">Edit candidates</a>
|
<a href="{{exam.get_cid_edit_url}}" class="edit-link" px-2>Edit candidates</a>
|
||||||
|
{% comment %} <button>Add group candidates</button>
|
||||||
|
<button>Remove group candidates</button> {% endcomment %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{{exam.get_user_edit_url}}" class="edit-link">Edit candidates</a>
|
<a href="{{exam.get_user_edit_url}}" class="edit-link px-2">Edit candidates</a>
|
||||||
|
<form>
|
||||||
|
<input type="hidden" name="exam_id" value="{{exam.pk}}">
|
||||||
|
<input type="hidden" name="exam_type" value="{{exam.app_name}}">
|
||||||
|
<button
|
||||||
|
class="btn btn-sm px-2"
|
||||||
|
hx-post="{% url 'generic:user_group_add_candidates_to_exams' group.pk %}"
|
||||||
|
title="Add all group candidates to this exam"
|
||||||
|
name="action"
|
||||||
|
value="add"
|
||||||
|
>Add group candidates</button>
|
||||||
|
<button
|
||||||
|
hx-post="{% url 'generic:user_group_add_candidates_to_exams' group.pk %}"
|
||||||
|
title="Remove all group candidates to this exam"
|
||||||
|
class="btn btn-sm px-2"
|
||||||
|
name="action"
|
||||||
|
value="remove"
|
||||||
|
>Remove group candidates</button>
|
||||||
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<span class="cid-number">
|
|
||||||
|
|
||||||
|
<div class="px-2 ms-auto ">
|
||||||
{% if group_type == "cid" %}
|
{% if group_type == "cid" %}
|
||||||
(Cid candidate count: {{exam.valid_cid_users.count}})
|
(Cid candidate count: {{exam.valid_cid_users.count}})
|
||||||
{% else %}
|
{% else %}
|
||||||
(User candidate count: {{exam.valid_user_users.count}})
|
(User candidate count: {{exam.valid_user_users.count}})
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</span>
|
</div>
|
||||||
</li>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
<style>
|
<style>
|
||||||
td, th { padding-left: 10px }
|
td, th { padding-left: 10px }
|
||||||
|
|
||||||
.cid-number {float: right}
|
|
||||||
|
|
||||||
.edit-link {
|
.edit-link {
|
||||||
font-size: smaller;
|
font-size: smaller;
|
||||||
opacity: 60%;
|
opacity: 60%;
|
||||||
|
|||||||
@@ -120,6 +120,16 @@ urlpatterns = [
|
|||||||
views.user_group_view_detail,
|
views.user_group_view_detail,
|
||||||
name="user_group_detail",
|
name="user_group_detail",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"user/group/<int:group_id>/add",
|
||||||
|
views.user_group_add_candidates_to_exams,
|
||||||
|
name="user_group_add_candidates_to_exams",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"user/group/<int:group_id>/",
|
||||||
|
views.user_group_view_detail,
|
||||||
|
name="user_group_detail",
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
"user/group/<int:pk>/exams",
|
"user/group/<int:pk>/exams",
|
||||||
views.UserGroupExamUpdate.as_view(),
|
views.UserGroupExamUpdate.as_view(),
|
||||||
|
|||||||
@@ -133,6 +133,17 @@ class CidManagerRequiredMixin(UserPassesTestMixin):
|
|||||||
# return obj
|
# return obj
|
||||||
# raise PermissionDenied() # or Http404
|
# raise PermissionDenied() # or Http404
|
||||||
|
|
||||||
|
def get_exam_model_from_app_name(app_name: str) -> ExamBase:
|
||||||
|
EXAM_MAP = {
|
||||||
|
"physics": PhysicsExam,
|
||||||
|
"anatomy": AnatomyExam,
|
||||||
|
"rapids": RapidsExam,
|
||||||
|
"longs": LongsExam,
|
||||||
|
"sbas": SbasExam,
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXAM_MAP[app_name]
|
||||||
|
|
||||||
|
|
||||||
def normaliseRapidsScore(score):
|
def normaliseRapidsScore(score):
|
||||||
if score == 49:
|
if score == 49:
|
||||||
@@ -2709,6 +2720,30 @@ def cid_group_view_all(request):
|
|||||||
{"groups": groups, "view_all": True},
|
{"groups": groups, "view_all": True},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@user_is_cid_user_manager
|
||||||
|
def user_group_add_candidates_to_exams(request, group_id):
|
||||||
|
if request.htmx:
|
||||||
|
group = get_object_or_404(UserUserGroup, pk=group_id)
|
||||||
|
|
||||||
|
exam_id = request.POST.get("exam_id")
|
||||||
|
exam_type = request.POST.get("exam_type")
|
||||||
|
|
||||||
|
ExamModel = get_exam_model_from_app_name(exam_type)
|
||||||
|
|
||||||
|
exam = get_object_or_404(ExamModel, pk=exam_id)
|
||||||
|
|
||||||
|
if request.POST.get("action") == "remove":
|
||||||
|
exam.valid_user_users.remove(*group.users.all())
|
||||||
|
return HttpResponse(f"Candidates removed")
|
||||||
|
else:
|
||||||
|
exam.valid_user_users.add(*group.users.all())
|
||||||
|
return HttpResponse(f"Candidates added")
|
||||||
|
#exam.save()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
raise PermissionDenied() # or Http404
|
||||||
|
pass
|
||||||
|
|
||||||
@user_is_cid_user_manager
|
@user_is_cid_user_manager
|
||||||
def user_group_view_detail(request, group_id):
|
def user_group_view_detail(request, group_id):
|
||||||
|
|||||||
Reference in New Issue
Block a user