improve group management
This commit is contained in:
+190
-3
@@ -70,7 +70,6 @@ class ExamFormMixin:
|
|||||||
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()
|
||||||
|
|
||||||
|
|
||||||
self.fields["cid_user_groups"] = ModelMultipleChoiceField(
|
self.fields["cid_user_groups"] = ModelMultipleChoiceField(
|
||||||
required=False,
|
required=False,
|
||||||
queryset=cid_user_group_queryset,
|
queryset=cid_user_group_queryset,
|
||||||
@@ -79,6 +78,7 @@ class ExamFormMixin:
|
|||||||
required=False,
|
required=False,
|
||||||
queryset=user_user_group_queryset,
|
queryset=user_user_group_queryset,
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
fields = [
|
fields = [
|
||||||
"name",
|
"name",
|
||||||
@@ -129,9 +129,11 @@ class ExaminationForm(ModelForm):
|
|||||||
model = Examination
|
model = Examination
|
||||||
fields = ["examination", "modality"]
|
fields = ["examination", "modality"]
|
||||||
|
|
||||||
|
|
||||||
class ExaminationMergeForm(Form):
|
class ExaminationMergeForm(Form):
|
||||||
examination_to_merge_into = ModelChoiceField(queryset=Examination.objects.all())
|
examination_to_merge_into = ModelChoiceField(queryset=Examination.objects.all())
|
||||||
|
|
||||||
|
|
||||||
class QuestionNoteForm(ModelForm):
|
class QuestionNoteForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = QuestionNote
|
model = QuestionNote
|
||||||
@@ -172,7 +174,6 @@ class QuestionNoteForm(ModelForm):
|
|||||||
|
|
||||||
|
|
||||||
class CidUserForm(ModelForm):
|
class CidUserForm(ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CidUser
|
model = CidUser
|
||||||
fields = [
|
fields = [
|
||||||
@@ -187,6 +188,7 @@ class CidUserForm(ModelForm):
|
|||||||
"group",
|
"group",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class CidUserExamForm(ModelForm):
|
class CidUserExamForm(ModelForm):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
if kwargs.get("instance"):
|
if kwargs.get("instance"):
|
||||||
@@ -289,17 +291,18 @@ class CidUserExamForm(ModelForm):
|
|||||||
self.save_m2m()
|
self.save_m2m()
|
||||||
|
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CidUser
|
model = CidUser
|
||||||
fields = []
|
fields = []
|
||||||
|
|
||||||
|
|
||||||
class CidUserGroupModelChoiceField(ModelMultipleChoiceField):
|
class CidUserGroupModelChoiceField(ModelMultipleChoiceField):
|
||||||
def label_from_instance(self, obj):
|
def label_from_instance(self, obj):
|
||||||
return f"{obj.cid} [{obj.email}]"
|
return f"{obj.cid} [{obj.email}]"
|
||||||
|
|
||||||
|
|
||||||
class CidUserGroupForm(ModelForm):
|
class CidUserGroupForm(ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CidUserGroup
|
model = CidUserGroup
|
||||||
fields = ["name", "archive"]
|
fields = ["name", "archive"]
|
||||||
@@ -322,6 +325,190 @@ class UserUserGroupForm(ModelForm):
|
|||||||
fields = ["name", "archive", "users"]
|
fields = ["name", "archive", "users"]
|
||||||
|
|
||||||
|
|
||||||
|
class UserGroupExamForm(ModelForm):
|
||||||
|
GROUP_TYPES = [
|
||||||
|
"anatomy_user_user_groups",
|
||||||
|
"rapid_user_user_groups",
|
||||||
|
"longs_user_user_groups",
|
||||||
|
"physics_user_user_groups",
|
||||||
|
"sba_user_user_groups",
|
||||||
|
]
|
||||||
|
# users = UserUserGroupModelChoiceField(
|
||||||
|
# required=False,
|
||||||
|
# queryset=User.objects.all(),
|
||||||
|
# widget=FilteredSelectMultiple(verbose_name="Users", is_stacked=False),
|
||||||
|
# )
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
if kwargs.get("instance"):
|
||||||
|
# We get the 'initial' keyword argument or initialize it
|
||||||
|
# as a dict if it didn't exist.
|
||||||
|
initial = kwargs.setdefault("initial", {})
|
||||||
|
# The widget for a ModelMultipleChoiceField expects
|
||||||
|
# a list of primary key for the selected data.
|
||||||
|
for groups in self.GROUP_TYPES:
|
||||||
|
#instance.anatomy_cid_user_groups.clear()
|
||||||
|
#obj = getattr(instance,groups)
|
||||||
|
initial[groups] = [
|
||||||
|
t.pk for t in getattr(kwargs["instance"],groups).all()
|
||||||
|
]
|
||||||
|
|
||||||
|
ModelForm.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
super(UserGroupExamForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
self.fields["anatomy_user_user_groups"] = ModelMultipleChoiceField(
|
||||||
|
required=False,
|
||||||
|
queryset=AnatomyExam.objects.filter(archive=False),
|
||||||
|
widget=FilteredSelectMultiple(
|
||||||
|
verbose_name="Anatomy Exams", is_stacked=False
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.fields["rapid_user_user_groups"] = ModelMultipleChoiceField(
|
||||||
|
required=False,
|
||||||
|
queryset=RapidsExam.objects.filter(archive=False),
|
||||||
|
widget=FilteredSelectMultiple(verbose_name="Rapid Exams", is_stacked=False),
|
||||||
|
)
|
||||||
|
self.fields["longs_user_user_groups"] = ModelMultipleChoiceField(
|
||||||
|
required=False,
|
||||||
|
queryset=LongsExam.objects.filter(archive=False),
|
||||||
|
widget=FilteredSelectMultiple(verbose_name="Longs Exams", is_stacked=False),
|
||||||
|
)
|
||||||
|
self.fields["physics_user_user_groups"] = ModelMultipleChoiceField(
|
||||||
|
required=False,
|
||||||
|
queryset=PhysicsExam.objects.filter(archive=False),
|
||||||
|
widget=FilteredSelectMultiple(
|
||||||
|
verbose_name="Physics Exams", is_stacked=False
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.fields["sba_user_user_groups"] = ModelMultipleChoiceField(
|
||||||
|
required=False,
|
||||||
|
queryset=SbasExam.objects.filter(archive=False),
|
||||||
|
widget=FilteredSelectMultiple(verbose_name="Sbas Exams", is_stacked=False),
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = UserUserGroup
|
||||||
|
fields = []
|
||||||
|
|
||||||
|
def save(self, commit=True):
|
||||||
|
# Get the unsaved Long instance
|
||||||
|
instance = ModelForm.save(self, False)
|
||||||
|
|
||||||
|
# Prepare a 'save_m2m' method for the form,
|
||||||
|
old_save_m2m = self.save_m2m
|
||||||
|
|
||||||
|
def save_m2m():
|
||||||
|
old_save_m2m()
|
||||||
|
|
||||||
|
for groups in self.GROUP_TYPES:
|
||||||
|
#instance.anatomy_cid_user_groups.clear()
|
||||||
|
obj = getattr(instance,groups)
|
||||||
|
obj.clear()
|
||||||
|
for exam in self.cleaned_data[groups]:
|
||||||
|
obj.add(exam.pk)
|
||||||
|
|
||||||
|
self.save_m2m = save_m2m
|
||||||
|
|
||||||
|
# Do we need to save all changes now?
|
||||||
|
# if commit:
|
||||||
|
instance.save()
|
||||||
|
self.save_m2m()
|
||||||
|
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|
||||||
|
class CidGroupExamForm(ModelForm):
|
||||||
|
GROUP_TYPES = [
|
||||||
|
"anatomy_cid_user_groups",
|
||||||
|
"rapid_cid_user_groups",
|
||||||
|
"longs_cid_user_groups",
|
||||||
|
"physics_cid_user_groups",
|
||||||
|
"sba_cid_user_groups",
|
||||||
|
]
|
||||||
|
|
||||||
|
# users = CidUserGroupModelChoiceField(
|
||||||
|
# required=False,
|
||||||
|
# queryset=User.objects.all(),
|
||||||
|
# widget=FilteredSelectMultiple(verbose_name="Users", is_stacked=False),
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
if kwargs.get("instance"):
|
||||||
|
# We get the 'initial' keyword argument or initialize it
|
||||||
|
# as a dict if it didn't exist.
|
||||||
|
initial = kwargs.setdefault("initial", {})
|
||||||
|
# The widget for a ModelMultipleChoiceField expects
|
||||||
|
# a list of primary key for the selected data.
|
||||||
|
for groups in self.GROUP_TYPES:
|
||||||
|
#instance.anatomy_cid_user_groups.clear()
|
||||||
|
#obj = getattr(instance,groups)
|
||||||
|
initial[groups] = [
|
||||||
|
t.pk for t in getattr(kwargs["instance"],groups).all()
|
||||||
|
]
|
||||||
|
|
||||||
|
ModelForm.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
super(CidGroupExamForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
self.fields["anatomy_cid_user_groups"] = ModelMultipleChoiceField(
|
||||||
|
required=False,
|
||||||
|
queryset=AnatomyExam.objects.filter(archive=False),
|
||||||
|
widget=FilteredSelectMultiple(
|
||||||
|
verbose_name="Anatomy Exams", is_stacked=False
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.fields["rapid_cid_user_groups"] = ModelMultipleChoiceField(
|
||||||
|
required=False,
|
||||||
|
queryset=RapidsExam.objects.filter(archive=False),
|
||||||
|
widget=FilteredSelectMultiple(verbose_name="Rapid Exams", is_stacked=False),
|
||||||
|
)
|
||||||
|
self.fields["longs_cid_user_groups"] = ModelMultipleChoiceField(
|
||||||
|
required=False,
|
||||||
|
queryset=LongsExam.objects.filter(archive=False),
|
||||||
|
widget=FilteredSelectMultiple(verbose_name="Longs Exams", is_stacked=False),
|
||||||
|
)
|
||||||
|
self.fields["physics_cid_user_groups"] = ModelMultipleChoiceField(
|
||||||
|
required=False,
|
||||||
|
queryset=PhysicsExam.objects.filter(archive=False),
|
||||||
|
widget=FilteredSelectMultiple(
|
||||||
|
verbose_name="Physics Exams", is_stacked=False
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.fields["sba_cid_user_groups"] = ModelMultipleChoiceField(
|
||||||
|
required=False,
|
||||||
|
queryset=SbasExam.objects.filter(archive=False),
|
||||||
|
widget=FilteredSelectMultiple(verbose_name="Sbas Exams", is_stacked=False),
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = CidUserGroup
|
||||||
|
fields = []
|
||||||
|
|
||||||
|
def save(self, commit=True):
|
||||||
|
# Get the unsaved Long instance
|
||||||
|
instance = ModelForm.save(self, False)
|
||||||
|
|
||||||
|
# Prepare a 'save_m2m' method for the form,
|
||||||
|
old_save_m2m = self.save_m2m
|
||||||
|
|
||||||
|
def save_m2m():
|
||||||
|
old_save_m2m()
|
||||||
|
|
||||||
|
for groups in self.GROUP_TYPES:
|
||||||
|
#instance.anatomy_cid_user_groups.clear()
|
||||||
|
obj = getattr(instance,groups)
|
||||||
|
obj.clear()
|
||||||
|
for exam in self.cleaned_data[groups]:
|
||||||
|
obj.add(exam.pk)
|
||||||
|
|
||||||
|
self.save_m2m = save_m2m
|
||||||
|
|
||||||
|
# Do we need to save all changes now?
|
||||||
|
# if commit:
|
||||||
|
instance.save()
|
||||||
|
self.save_m2m()
|
||||||
|
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|
||||||
# class UserForm(ModelForm):
|
# class UserForm(ModelForm):
|
||||||
# class Meta:
|
# class Meta:
|
||||||
# model = User
|
# model = User
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
{% extends 'generic/base.html' %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block navigation %}
|
||||||
|
{{block.super}}
|
||||||
|
<br/>
|
||||||
|
Group: {{group.name}}->
|
||||||
|
{% if group_type == "cid" %}
|
||||||
|
|
||||||
|
{% if not group %}
|
||||||
|
<a href="{% url 'generic:cid_group_detail' cidusergroup.pk %}">Group</a> /
|
||||||
|
<a href="{% url 'generic:cid_group_update' cidusergroup.pk %}">Edit Users</a> /
|
||||||
|
<a href="{% url 'generic:cid_group_exams' cidusergroup.pk %}">Edit Exams</a> /
|
||||||
|
<a href="{% url 'generic:cid_group_delete' cidusergroup.pk %}">Delete</a>
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
<a href="{% url 'generic:cid_group_detail' group.pk %}">Group</a> /
|
||||||
|
<a href="{% url 'generic:cid_group_update' group.pk %}">Edit Users</a> /
|
||||||
|
<a href="{% url 'generic:cid_group_exams' group.pk %}">Edit Exams</a> /
|
||||||
|
<a href="{% url 'generic:cid_group_delete' group.pk %}">Delete</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
<a href="{% url 'generic:user_group_detail' group.pk %}">Group</a> /
|
||||||
|
<a href="{% url 'generic:user_group_update' group.pk %}">Edit Users</a> /
|
||||||
|
<a href="{% url 'generic:user_group_exams' group.pk %}">Edit Exams</a> /
|
||||||
|
<a href="{% url 'generic:user_group_delete' group.pk %}">Delete</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
{% extends 'generic/base.html' %}
|
{% extends 'generic/cid_group_base.html' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h2>Group: {{group.name}}</h2>
|
<h2>Group: {{group.name}}</h2>
|
||||||
@@ -39,7 +39,12 @@
|
|||||||
{% 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.
|
||||||
|
{% if group_type == "cid" %}
|
||||||
|
Add more <a href='{% url "generic:cid_group_exams" group.pk %}'>here</a>.
|
||||||
|
{% else %}
|
||||||
|
Add more <a href='{% url "generic:user_group_exams" group.pk %}'>here</a>.
|
||||||
|
{% endif %}
|
||||||
{% 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>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
</form>
|
</form>
|
||||||
|
|
||||||
<h2>Exams</h2>
|
<h2>Exams</h2>
|
||||||
<p>The user is currently part of the following exams</p>
|
The group is currently associated with the following exams.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
{% with object.get_cid_exams as exam_map %}
|
{% with object.get_cid_exams as exam_map %}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{% extends "generic/base.html" %}
|
{% extends 'generic/cid_group_base.html' %}
|
||||||
<!-- {% load static from static %} -->
|
<!-- {% load static from static %} -->
|
||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ urlpatterns = [
|
|||||||
name="cid_group_detail",
|
name="cid_group_detail",
|
||||||
),
|
),
|
||||||
path("cids/group/<int:pk>/email", views.group_email, name="group_email"),
|
path("cids/group/<int:pk>/email", views.group_email, name="group_email"),
|
||||||
|
path("cids/group/<int:pk>/exams", views.CidGroupExamUpdate.as_view(), name="cid_group_exams"),
|
||||||
path(
|
path(
|
||||||
"cids/group/<int:pk>/email_results",
|
"cids/group/<int:pk>/email_results",
|
||||||
views.group_email_results,
|
views.group_email_results,
|
||||||
@@ -105,6 +106,7 @@ urlpatterns = [
|
|||||||
views.user_group_view_detail,
|
views.user_group_view_detail,
|
||||||
name="user_group_detail",
|
name="user_group_detail",
|
||||||
),
|
),
|
||||||
|
path("user/group/<int:pk>/exams", views.UserGroupExamUpdate.as_view(), name="user_group_exams"),
|
||||||
path(
|
path(
|
||||||
"user/group/<int:pk>/update",
|
"user/group/<int:pk>/update",
|
||||||
views.UserUserGroupUpdate.as_view(),
|
views.UserUserGroupUpdate.as_view(),
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ from pathlib import Path
|
|||||||
import secrets
|
import secrets
|
||||||
import statistics
|
import statistics
|
||||||
import threading
|
import threading
|
||||||
|
from typing import Any
|
||||||
from dal import autocomplete
|
from dal import autocomplete
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
@@ -51,12 +52,15 @@ from generic.tables import CidUserExamTable, CidUserTable, ExaminationTable
|
|||||||
from generic.mixins import SuperuserRequiredMixin
|
from generic.mixins import SuperuserRequiredMixin
|
||||||
|
|
||||||
from .forms import (
|
from .forms import (
|
||||||
|
CidGroupExamForm,
|
||||||
CidUserForm,
|
CidUserForm,
|
||||||
CidUserExamForm,
|
CidUserExamForm,
|
||||||
ExaminationForm,
|
ExaminationForm,
|
||||||
CidUserGroupForm,
|
CidUserGroupForm,
|
||||||
ExaminationMergeForm,
|
ExaminationMergeForm,
|
||||||
SupervisorForm,
|
SupervisorForm,
|
||||||
|
UserGroupExamForm,
|
||||||
|
CidGroupExamForm,
|
||||||
UserUserForm,
|
UserUserForm,
|
||||||
UserUserGroupForm,
|
UserUserGroupForm,
|
||||||
)
|
)
|
||||||
@@ -2963,6 +2967,11 @@ class CidUserGroupUpdate(RevisionMixin, CidManagerRequiredMixin, UpdateView):
|
|||||||
model = CidUserGroup
|
model = CidUserGroup
|
||||||
form_class = CidUserGroupForm
|
form_class = CidUserGroupForm
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context["group_type"] = "cid"
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
class UserUserGroupCreate(RevisionMixin, CidManagerRequiredMixin, CreateView):
|
class UserUserGroupCreate(RevisionMixin, CidManagerRequiredMixin, CreateView):
|
||||||
model = UserUserGroup
|
model = UserUserGroup
|
||||||
@@ -2973,12 +2982,33 @@ class UserUserGroupUpdate(RevisionMixin, CidManagerRequiredMixin, UpdateView):
|
|||||||
model = UserUserGroup
|
model = UserUserGroup
|
||||||
form_class = UserUserGroupForm
|
form_class = UserUserGroupForm
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context["group_type"] = "user"
|
||||||
|
return context
|
||||||
|
|
||||||
class UserUserGroupDelete(RevisionMixin, CidManagerRequiredMixin, DeleteView):
|
class UserUserGroupDelete(RevisionMixin, CidManagerRequiredMixin, DeleteView):
|
||||||
model = UserUserGroup
|
model = UserUserGroup
|
||||||
template_name = "confirm_delete.html"
|
template_name = "confirm_delete.html"
|
||||||
success_url = reverse_lazy("generic:user_group_view")
|
success_url = reverse_lazy("generic:user_group_view")
|
||||||
|
|
||||||
|
class UserGroupExamUpdate(CidManagerRequiredMixin, UpdateView):
|
||||||
|
model = UserUserGroup
|
||||||
|
form_class = UserGroupExamForm
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context["group_type"] = "user"
|
||||||
|
return context
|
||||||
|
|
||||||
|
class CidGroupExamUpdate(CidManagerRequiredMixin, UpdateView):
|
||||||
|
model = CidUserGroup
|
||||||
|
form_class = CidGroupExamForm
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context["group_type"] = "cid"
|
||||||
|
return context
|
||||||
|
|
||||||
class ExamCreateBase(RevisionMixin, LoginRequiredMixin, CreateView):
|
class ExamCreateBase(RevisionMixin, LoginRequiredMixin, CreateView):
|
||||||
template_name = "exam_create_form.html"
|
template_name = "exam_create_form.html"
|
||||||
|
|||||||
Reference in New Issue
Block a user