More improvements to user management

This commit is contained in:
Ross
2022-11-21 12:43:46 +00:00
parent be3f420c68
commit 0b90308394
21 changed files with 321 additions and 44 deletions
+30 -1
View File
@@ -3,7 +3,7 @@ import django_filters
from django.contrib.auth.models import User
from generic.models import CidUser
from generic.models import CidUser, Supervisor, UserGrades
class CidUserFilter(django_filters.FilterSet):
@@ -32,3 +32,32 @@ class CidUserFilter(django_filters.FilterSet):
return parent.filter(active=True)
return parent
class UserUserFilter(django_filters.FilterSet):
userprofile__grade = django_filters.ModelChoiceFilter(queryset=UserGrades.objects.all(),label="Grade")
userprofile__supervisor = django_filters.ModelChoiceFilter(queryset=Supervisor.objects.all(), label="Supervisor")
#has_supervisor = django_filters.BooleanFilter(field_name='supervisor', lookup_expr='isnull', exclude=True, label="Has Supervisor")
class Meta:
model = User
# fields = ("cid", "active", "internal_candidate", "group")
fields = {
"first_name": ["contains"],
"last_name": ["contains"],
#"active": ["exact"],
#"group": ["exact"],
#"group__name": ["contains"],
#"userprofile__grade": ["exact"],
#"userprofile__supervisor": ["exact"],
"email": ["contains"],
}
@property
def qs(self):
parent = super().qs
## filter_active = getattr(self.request, 'active', True)
#if "active" not in self.request.GET:
# return parent.filter(active=True)
return parent
+12 -4
View File
@@ -14,7 +14,7 @@ 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, 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
@@ -228,7 +228,7 @@ class CidUserForm(ModelForm):
"internal_candidate",
"name",
"email",
"supervisor_email",
"supervisor",
"login_email_sent",
"results_email_sent",
"group",
@@ -263,12 +263,20 @@ class UserUserGroupForm(ModelForm):
# model = UserProfile
# fields = ["supervisor_name", "supervisor_email", "registration_number", "peninsula_trainee"]
GRADE_CHOICES = (
("ST1", "ST1"),
("ST2", "ST2"),
("ST3", "ST3"),
("ST4", "ST4"),
("ST5", "ST5"),
)
class UserUserForm(Form):
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 = IntegerField(min_value=1, max_value=6, required=False)
supervisor = CharField(max_length=255, required=False) # Needs to be a user/object ref
grade = ModelChoiceField(UserGrades.objects.all(), required=False)
supervisor = ModelChoiceField(Supervisor.objects.all(), required=False) # Needs to be a user/object ref
#
# class Meta:
#
@@ -0,0 +1,32 @@
# Generated by Django 3.2.13 on 2022-11-14 20:35
from django.db import migrations
def migrate_supervisors(apps, schema_editor):
UserProfile = apps.get_model("generic", "UserProfile")
for profile in UserProfile.objects.all():
if profile.supervisor_name and profile.supervisor_email:
Supervisor = apps.get_model("generic", "Supervisor")
s, created = Supervisor.objects.get_or_create(email=profile.supervisor_email, name=profile.supervisor_name)
if created:
s.save()
profile.supervisor = s
profile.save()
class Migration(migrations.Migration):
dependencies = [
('generic', '0043_alter_userprofile_supervisor'),
]
operations = [
migrations.RunPython(migrate_supervisors)
]
@@ -0,0 +1,21 @@
# Generated by Django 3.2.13 on 2022-11-14 21:03
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('generic', '0044_auto_20221114_2035'),
]
operations = [
migrations.RemoveField(
model_name='userprofile',
name='supervisor_email',
),
migrations.RemoveField(
model_name='userprofile',
name='supervisor_name',
),
]
@@ -0,0 +1,23 @@
# Generated by Django 3.2.13 on 2022-11-21 09:55
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('generic', '0045_auto_20221114_2103'),
]
operations = [
migrations.RemoveField(
model_name='ciduser',
name='supervisor_email',
),
migrations.AddField(
model_name='ciduser',
name='supervisor',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='cid_user', to='generic.supervisor'),
),
]
+3 -5
View File
@@ -339,7 +339,7 @@ class ExamBase(models.Model):
emails = [user.email]
supervisor_email = user.userprofile.supervisor_email
supervisor_email = user.userprofile.supervisor.email
if supervisor_email:
emails.append(supervisor_email)
@@ -438,7 +438,7 @@ class CidUser(models.Model):
internal_candidate = models.BooleanField(default=False)
name = models.CharField(blank=True, max_length=255)
email = models.EmailField(blank=True)
supervisor_email = models.EmailField(blank=True)
supervisor = models.ForeignKey("Supervisor", on_delete=models.SET_NULL, blank=True, null=True, related_name="cid_user")
login_email_sent = models.BooleanField(default=False)
results_email_sent = models.BooleanField(default=False)
@@ -518,7 +518,7 @@ class CidUser(models.Model):
# Get a list of taken exams
msg = self.generate_exam_report()
emails = [self.email, self.supervisor_email]
emails = [self.email, self.supervisor.email]
if additional_emails:
emails.extend(additional_emails)
@@ -667,8 +667,6 @@ class UserGrades(models.Model):
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
supervisor_email = models.EmailField(blank=True)
supervisor_name = models.CharField(max_length=100, blank=True)
supervisor = models.ForeignKey("Supervisor", on_delete=models.SET_NULL, blank=True, null=True, related_name="trainee")
registration_number = models.CharField(max_length=25, blank=True)
grade = models.ForeignKey(UserGrades, null=True, blank=True, help_text="User grade", on_delete=models.CASCADE)
+58 -2
View File
@@ -9,6 +9,7 @@ from easy_thumbnails.exceptions import InvalidImageFormatError
from generic.models import CidUser
from django.contrib.auth.models import User
class ImageColumn(tables.Column):
def render(self, value):
@@ -65,7 +66,10 @@ class CidUserTable(tables.Table):
def render_emails(self, value, record):
print(self)
return format_html("""{}\n[{}]""", record.email, record.supervisor_email)
if record.supervisor is not None:
return format_html("""{}\n[{}]""", record.email, record.supervisor.email)
else:
return format_html(record.email)
class CidUserExamTable(tables.Table):
# edit = tables.LinkColumn(
@@ -112,7 +116,59 @@ class CidUserExamTable(tables.Table):
)
def render_emails(self, value, record):
return format_html("""{}\n[{}]""", record.email, record.supervisor_email)
if record.supervisor is not None:
return format_html("""{}\n[{}]""", record.email, record.supervisor.email)
else:
return format_html(record.email)
# def render_cid(self, value, record):
# return format_html("""<a href="#" onclick="return window.create_popup_window('/longs/series/{}', 'Series')" >Popup</a>""", record.pk)
class UserUserTable(tables.Table):
# edit = tables.LinkColumn(
# "anatomy:anatomy_question_update", text="Edit", args=[A("pk")], orderable=False
# )
user = tables.Column(
linkify={"viewname": "account_profile", "args":[A("username")]}, orderable=True, verbose_name="User", empty_values=()
)
supervisor = tables.Column(
linkify={"viewname": "generic:supervisor_detail", "args":[A("userprofile.supervisor.pk")]}, orderable=True, verbose_name="Supervisor", accessor=A("userprofile.supervisor")
)
selection = tables.CheckBoxColumn(accessor="pk", orderable=False)
edit = tables.Column(
empty_values=(), linkify={"viewname": "account_update", "args":[A("username")]}, orderable=True, verbose_name="Edit",
)
class Meta:
model = User
template_name = "django_tables2/bootstrap4.html"
fields = (
# "cid",
#"userprofile",
"userprofile.grade",
#"userprofile.supervisor",
# "email",
)
sequence = ("user", "userprofile.grade", "supervisor", "edit")
def __init__(self, data=None, *args, **kwargs):
super().__init__(
data.prefetch_related(
"supervisor",
"userprofile",
#"userprofile.grade",
),
*args,
**kwargs,
)
# This should be avoidable?
def render_edit(self, value, record):
return "Edit"
def render_user(self, value, record):
return format_html("{} {}<br/>{}<br/>{}", record.first_name, record.last_name, record.username, record.email)
+1 -1
View File
@@ -9,7 +9,7 @@
<li><a href="{% url 'generic:update_cid' cid.pk %}">{{cid.cid}}</a> [{{cid.passcode}}] {{cid.name}} /
Email: {{cid.email}}
{% if cid.supervisor_email %} / Supervisor email: {{cid.supervisor_email}}{% endif %} <br />
{% if cid.supervisor %} / Supervisor email: {{cid.supervisor.email}}{% endif %} <br />
Internal candidate: {{cid.internal_candidate}}
{% if cid.login_email_sent %} / Login email sent{% endif %}
{% if cid.results_email_sent %} / Results email sent{% endif %}
+1 -1
View File
@@ -13,7 +13,7 @@
{% else %}
data-posturl='{{user.get_email_details_url}}'
{% endif %}
>{{user.cid}}/{{user.name}}: {{user.email}} [{{user.supervisor_email}}] </li>
>{{user.cid}}/{{user.name}}: {{user.email}} [{{user.supervisor.email}}] </li>
{% endfor %}
</ul>
@@ -14,7 +14,7 @@
{% endblock %}
{% block content %}
<h2>Edit User / {{ciduser.cid}}</h2>
Use this form to create a user.
Use this form to create a user. Only existing supervisors can be added (create it first or add it later if it does not exist).
{% if errors %}
<div class="alert alert-info" role="alert">{{errors}}</a></div>
{% endif %}
+31
View File
@@ -0,0 +1,31 @@
{% extends 'generic/base.html' %}
{% load render_table from django_tables2 %}
{% block css %}
{% endblock %}
{% block content %}
<div id="view-filter-options">
<details class="filter">
<summary>
<h3>Filter Users </h3>
</summary>
<form action="" method="get">
{{ filter.form }}
<input class="btn btn-primary btn-sm mt-1 mb-1" type="submit" />
</form>
</details>
</div>
<div>
<span id="manage-span">
{% render_table table %}
</span>
</div>
<a href="{% url 'accounts_bulk_create' %}">Bulk create users</a>
<a href="{% url 'create_user' %}">Create single user</a>
{% endblock %}
+5 -5
View File
@@ -2540,15 +2540,15 @@ def create_user(request, context=None):
user_profile = UserProfile.objects.get(user=new_user)
user_profile.peninsula_trainee = True
#if "supervisor_email" in user:
# user_profile.supervisor_email = user["supervisor_email"]
#if "supervisor_name" in user:
# user_profile.supervisor_name = user["supervisor_name"]
if request.POST["grade"]:
grade = UserGrades.objects.get(name=f"ST{ request.POST['grade'] }")
grade = UserGrades.objects.get(pk=request.POST["grade"])
user_profile.grade = grade
if request.POST["supervisor"]:
supervisor = Supervisor.objects.get(pk=request.POST["supervisor"])
user_profile.supervisor = supervisor
user_profile.save()