Complete supervisor model and start improving forms

This commit is contained in:
Ross
2022-11-28 09:50:07 +00:00
parent 653baa85ff
commit 747bf93373
27 changed files with 309 additions and 183 deletions
+62 -19
View File
@@ -7,14 +7,22 @@ from django.forms import (
CharField,
HiddenInput,
EmailField,
IntegerField
IntegerField,
)
from django.forms import inlineformset_factory
from atlas.models import CaseCollection
from django.contrib.auth.models import User
from generic.models import CidUser, CidUserGroup, Examination, QuestionNote, Supervisor, UserGrades, UserProfile, UserUserGroup
from generic.models import (
CidUser,
CidUserGroup,
Examination,
QuestionNote,
Supervisor,
UserGrades,
UserProfile,
UserUserGroup,
)
from django.contrib.admin.widgets import FilteredSelectMultiple
from django.forms.widgets import RadioSelect, TextInput, Textarea
@@ -50,6 +58,7 @@ from sbas.models import CidUserAnswer as SbasCidUserAnswer
from sbas.models import Exam as SbasExam
from sbas.models import Question as SbasQuestion
class ExamFormMixin:
class Meta:
fields = [
@@ -64,7 +73,7 @@ class ExamFormMixin:
"archive",
"cid_user_groups",
"user_user_groups",
#"author",
# "author",
]
def save(self, commit=True):
@@ -75,6 +84,7 @@ class ExamFormMixin:
return instance
class ExamAuthorFormMixin(ModelForm):
class Meta:
fields = ["author"]
@@ -133,7 +143,6 @@ class QuestionNoteForm(ModelForm):
class CidUserForm(ModelForm):
def __init__(self, *args, **kwargs):
if kwargs.get("instance"):
# We get the 'initial' keyword argument or initialize it
@@ -141,12 +150,22 @@ class CidUserForm(ModelForm):
initial = kwargs.setdefault("initial", {})
# The widget for a ModelMultipleChoiceField expects
# a list of primary key for the selected data.
initial["physics_exams"] = [t.pk for t in kwargs["instance"].physics_exams.all()]
initial["anatomy_exams"] = [t.pk for t in kwargs["instance"].anatomy_exams.all()]
initial["physics_exams"] = [
t.pk for t in kwargs["instance"].physics_exams.all()
]
initial["anatomy_exams"] = [
t.pk for t in kwargs["instance"].anatomy_exams.all()
]
initial["sba_exams"] = [t.pk for t in kwargs["instance"].sba_exams.all()]
initial["rapid_exams"] = [t.pk for t in kwargs["instance"].rapid_exams.all()]
initial["longs_exams"] = [t.pk for t in kwargs["instance"].longs_exams.all()]
initial["casecollection_exams"] = [t.pk for t in kwargs["instance"].casecollection_exams.all()]
initial["rapid_exams"] = [
t.pk for t in kwargs["instance"].rapid_exams.all()
]
initial["longs_exams"] = [
t.pk for t in kwargs["instance"].longs_exams.all()
]
initial["casecollection_exams"] = [
t.pk for t in kwargs["instance"].casecollection_exams.all()
]
ModelForm.__init__(self, *args, **kwargs)
@@ -155,12 +174,16 @@ class CidUserForm(ModelForm):
self.fields["physics_exams"] = ModelMultipleChoiceField(
required=False,
queryset=PhysicsExam.objects.filter(archive=False),
widget=FilteredSelectMultiple(verbose_name="Physics Exams", is_stacked=False),
widget=FilteredSelectMultiple(
verbose_name="Physics Exams", is_stacked=False
),
)
self.fields["anatomy_exams"] = ModelMultipleChoiceField(
required=False,
queryset=AnatomyExam.objects.filter(archive=False),
widget=FilteredSelectMultiple(verbose_name="Anatomy Exams", is_stacked=False),
widget=FilteredSelectMultiple(
verbose_name="Anatomy Exams", is_stacked=False
),
)
self.fields["sba_exams"] = ModelMultipleChoiceField(
required=False,
@@ -180,7 +203,9 @@ class CidUserForm(ModelForm):
self.fields["casecollection_exams"] = ModelMultipleChoiceField(
required=False,
queryset=CaseCollection.objects.filter(archive=False),
widget=FilteredSelectMultiple(verbose_name="Case Collection", is_stacked=False),
widget=FilteredSelectMultiple(
verbose_name="Case Collection", is_stacked=False
),
)
def save(self, commit=True):
@@ -219,7 +244,7 @@ class CidUserForm(ModelForm):
self.save_m2m()
return instance
class Meta:
model = CidUser
fields = [
@@ -234,31 +259,42 @@ class CidUserForm(ModelForm):
"group",
]
class CidUserGroupModelChoiceField(ModelMultipleChoiceField):
def label_from_instance(self, obj):
return f"{obj.cid} [{obj.email}]"
class CidUserGroupForm(ModelForm):
class Meta:
model = CidUserGroup
fields = ["name", "archive"]
class UserUserGroupModelChoiceField(ModelMultipleChoiceField):
def label_from_instance(self, obj):
return f"{obj.username} ({obj.userprofile.grade}) [{obj.email}]"
class UserUserGroupForm(ModelForm):
users = UserUserGroupModelChoiceField(
required=False,
queryset=User.objects.all(),
widget=FilteredSelectMultiple(verbose_name="Users", is_stacked=False),
)
class Meta:
model = UserUserGroup
fields = ["name", "archive", "users"]
#class UserForm(ModelForm):
# class UserForm(ModelForm):
# class Meta:
# model = User
# fields = ["first_name", "last_name", "email"]
#
#class UserProfileForm(ModelForm):
# class UserProfileForm(ModelForm):
# class Meta:
# model = UserProfile
# fields = ["supervisor_name", "supervisor_email", "registration_number", "peninsula_trainee"]
@@ -271,18 +307,25 @@ GRADE_CHOICES = (
("ST5", "ST5"),
)
class UserUserForm(Form):
username = EmailField(required=True, help_text="Username / email should be the same. Ideally this should be an nhs email.")
username = EmailField(
required=True,
help_text="Username / email should be the same. Ideally this should be an nhs email.",
)
first_name = CharField(max_length=255, required=True)
last_name = CharField(max_length=255, required=True)
grade = ModelChoiceField(UserGrades.objects.all(), required=False)
supervisor = ModelChoiceField(Supervisor.objects.all(), required=False) # Needs to be a user/object ref
supervisor = ModelChoiceField(
Supervisor.objects.all(), required=False
) # Needs to be a user/object ref
#
# class Meta:
#
# fields = ("username", "first_name", "last_name")
class SupervisorForm(ModelForm):
class Meta:
model = Supervisor
exclude = ("",)
exclude = ("",)
@@ -0,0 +1,29 @@
# Generated by Django 3.2.13 on 2022-11-21 16:37
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('generic', '0046_auto_20221121_0955'),
]
operations = [
migrations.AlterField(
model_name='supervisor',
name='email',
field=models.EmailField(help_text='The (nhs.net) email address of the supervisor', max_length=254, unique=True),
),
migrations.AlterField(
model_name='supervisor',
name='name',
field=models.CharField(help_text='Name of the supervisor', max_length=255),
),
migrations.AlterField(
model_name='supervisor',
name='site',
field=models.ForeignKey(blank=True, help_text='Hospital site at which the supervisor is based', null=True, on_delete=django.db.models.deletion.SET_NULL, to='generic.site'),
),
]
+6 -6
View File
@@ -638,13 +638,13 @@ class CidUserGroup(models.Model):
class UserUserGroup(models.Model):
name = models.CharField(blank=True, max_length=50)
archive = models.BooleanField(default=False)
name = models.CharField(blank=True, max_length=50, help_text="Name of the User Group")
archive = models.BooleanField(default=False, help_text="Archived groups remain on the test system but are not displayed by default")
users = models.ManyToManyField(
settings.AUTH_USER_MODEL,
blank=True,
related_name="user_groups"
related_name="user_groups",
)
def __str__(self) -> str:
@@ -686,10 +686,10 @@ class Supervisor(models.Model):
This can be linked with a user account.
"""
email = models.EmailField(blank=True, unique=True, help_text="The (nhs.net) email address of the supervisor")
name = models.CharField(max_length=255, blank=True, help_text="Name of the supervisor")
email = models.EmailField(unique=True, help_text="The (nhs.net) email address of the supervisor")
name = models.CharField(max_length=255, help_text="Name of the supervisor")
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True, help_text="If the supervisor has an account on the test system that can be associated here")
site = models.ForeignKey("Site", on_delete=models.SET_NULL, null=True, blank=True)
site = models.ForeignKey("Site", on_delete=models.SET_NULL, null=True, blank=True, help_text="Hospital site at which the supervisor is based")
active = models.BooleanField(default=True)
def __str__(self) -> str:
+8 -3
View File
@@ -33,6 +33,7 @@ class CidUserTable(tables.Table):
#sba_exams = tables.ManyToManyColumn(verbose_name="SBA Exams")
#longs_exams = tables.ManyToManyColumn(verbose_name="Long Exams")
#anatomy_exams = tables.ManyToManyColumn(verbose_name="Anatomy Exams")
group = tables.Column(linkify=True)
selection = tables.CheckBoxColumn(accessor="pk", orderable=False)
@@ -143,6 +144,8 @@ class UserUserTable(tables.Table):
empty_values=(), linkify={"viewname": "account_update", "args":[A("username")]}, orderable=True, verbose_name="Edit",
)
user_groups = tables.ManyToManyColumn(verbose_name="Groups", linkify_item=True)
class Meta:
model = User
template_name = "django_tables2/bootstrap4.html"
@@ -150,17 +153,19 @@ class UserUserTable(tables.Table):
# "cid",
#"userprofile",
"userprofile.grade",
#"user_groups",
#"userprofile.supervisor",
# "email",
)
sequence = ("user", "userprofile.grade", "supervisor", "edit")
sequence = ("user", "userprofile.grade", "supervisor", "user_groups", "edit")
def __init__(self, data=None, *args, **kwargs):
super().__init__(
data.prefetch_related(
"supervisor",
"userprofile",
#"userprofile.grade",
"user_groups",
"userprofile__grade",
"supervisor",
),
*args,
**kwargs,
@@ -6,7 +6,7 @@
<a href="{% url 'generic:cid_group_create' %}">Create new group</a>
</p>
{% for group in groups %}
<p><a href="{% url 'generic:cid_group_detail' group.pk %}">{{group.name}}</a>
<p><a href="{% url 'generic:cid_group_detail' group.pk %}"><h4>{{group.name}}</h4></a>
<button class="small-url-button" data-url="{% url 'generic:group_email' pk=group.pk %}
">Email candidate details</button>
<button class="small-url-button" data-url="{% url 'generic:group_email_resend' pk=group.pk %}
+2 -1
View File
@@ -1,5 +1,6 @@
{% extends 'generic/base.html' %}
{% load crispy_forms_tags %}
{% load render_table from django_tables2 %}
{% block css %}
{% endblock %}
@@ -12,7 +13,7 @@
<h3>Filter CID Users </h3>
</summary>
<form action="" method="get">
{{ filter.form }}
{{ filter.form |crispy}}
<input class="btn btn-primary btn-sm mt-1 mb-1" type="submit" />
</form>
</details>
@@ -28,13 +28,19 @@
</table>
<input type="submit" class="submit-button" value="Submit" name="submit">
<p>Users can be added to the group <a href="{% url 'generic:manage_cids' %}">here</a></p>
<h3>Users</h3>
{% if cidusergroup.GetGroupUsers %}
{{cidusergroup.GetGroupUsers}}
{% else %}
No users currently added to group.
{% endif %}
<ul>
{% for user in cidusergroup.ciduser_set.all %}
<li><a href="{% url 'generic:update_cid' user.pk %}">{{user.cid}}</a>: {{user.name}} [{{user.email}} {{user.last_name}}] {{user.userprofile.grade}}</li>
{% empty %}
<li>Group currently has no users.</li>
{% endfor %}
</ul>
Count: {{cidusergroup.ciduser_set.count}}
</form>
@@ -20,7 +20,7 @@
{% endfor %}
</ol>
{% else %}
This exam is not associated with any user groups. Edit and add a group to enable user management.
This exam is not associated with any user groups. <a href="{% url exam.app_name|add:':exam_update' exam.pk %}">Edit and add a group</a> to enable user management.
{% endif %}
<script>
@@ -1,5 +1,6 @@
{% extends "generic/supervisor_base.html" %}
<!-- {% load static from static %} -->
{% load crispy_forms_tags %}
{% block css %}
<style>
@@ -25,7 +26,7 @@ Use this form to create / edit a supervisor
{% csrf_token %}
<table>
{{ form.as_table }}
{{ form|crispy }}
</table>
<input type="submit" class="submit-button" value="Submit" name="submit">
</form>
@@ -5,8 +5,8 @@
<ul>
{% for supervisor in object_list %}
<li><a href="{% url 'generic:supervisor_detail' pk=supervisor.pk %}">Supervisor: {{supervisor.name}}</a>
<br/>{{supervisor.email}}
<li><a href="{% url 'generic:supervisor_detail' pk=supervisor.pk %}">{{supervisor.name}}</a>
<br/>{{supervisor.email}} [{{supervisor.site}}]
</li>
{% endfor %}
</ul>
@@ -1,7 +0,0 @@
<h2>Exam: {{ exam.name }}</h2>
<h3>Candidate: {{ cid|default_if_none:request.user.username }}</h3>
{% if view_all_results %}
<div class="alert alert-info" role="alert">
Exam state: Active [{{exam.active}}] / Published [{{exam.publish_results}}]
</div>
{% endif %}
@@ -1,5 +1,6 @@
{% extends "generic/base.html" %}
<!-- {% load static from static %} -->
{% load crispy_forms_tags %}
{% block css %}
{% endblock %}
@@ -18,29 +19,32 @@
{% else %}
<h2>Add New Group</h2>
{% endif %}
Use this form to create / edit a CID user group.
<form action="" method="post" enctype="multipart/form-data" id="condition-form">
Use this form to create / edit a User group.<br/>
<form action="" method="post" enctype="multipart/form-data" id="condition-form" class="inline-form">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
{{ form|crispy }}
<input type="submit" class="submit-button" value="Submit" name="submit">
</form>
<div>
<h3>Users</h3>
<ul>
{% for user in userusergroup.users.all %}
<li>{{user}}</li>{% empty %}
<li><a href="{% url 'account_profile' user.username %}">{{user.username}}</a> [{{user.first_name}} {{user.last_name}}] {{user.userprofile.grade}}</li>
{% empty %}
<li>Group currently has no users.</li>
{% endfor %}
</ul>
Count: {{userusergroup.users.count}}
</div>
{% comment %} {% if userusergroup.users.all %}
{% comment %} {% if userusergroup.users.all %}
{{userusergroup.GetGroupUsers}}
{% else %}
No users currently added to group.
{% endif %} {% endcomment %}
</form>
{% endblock %}