More improvements to user management
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
<!--<script type="text/javascript" src="/admin/jsi18n/"></script>-->
|
||||
|
||||
<script type="text/javascript">
|
||||
let crsf_token = "{{csrf_token}}";
|
||||
let csrf_token = "{{csrf_token}}";
|
||||
let hash_url = false;
|
||||
document.addEventListener('drop', function (e) { e.preventDefault(); }, false);
|
||||
|
||||
|
||||
+30
-1
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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
@@ -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()
|
||||
|
||||
|
||||
@@ -92,9 +92,6 @@ class PopupLinkColumn(tables.Column):
|
||||
|
||||
return obj.get_thumbnail()[0]
|
||||
|
||||
def create_link(test):
|
||||
print(test)
|
||||
return "Hello"
|
||||
|
||||
class LongSeriesTable(tables.Table):
|
||||
edit = tables.LinkColumn(
|
||||
|
||||
+5
-1
@@ -60,6 +60,9 @@ urlpatterns = [
|
||||
path("sbas/", include("sbas.urls"), name="sbas"),
|
||||
path("generic/", include("generic.urls"), name="generic"),
|
||||
path("atlas/", include("atlas.urls"), name="atlas"),
|
||||
path(
|
||||
"accounts/check_users", views.accounts_check_users, name="accounts_check_users"
|
||||
),
|
||||
path(
|
||||
"accounts/bulk_create/", views.accounts_bulk_create, name="accounts_bulk_create"
|
||||
),
|
||||
@@ -76,7 +79,8 @@ urlpatterns = [
|
||||
views.UpdateUserProfileView.as_view(),
|
||||
name="account_profile_update",
|
||||
),
|
||||
path("accounts/", views.UserListView.as_view(), name="accounts_list"),
|
||||
path("accounts/", views.UserListTableView.as_view(), name="accounts_list"),
|
||||
#path("accounts/", views.UserListView.as_view(), name="accounts_list"),
|
||||
path("accounts/", include("django.contrib.auth.urls")),
|
||||
path("accounts/profile", views.profile, name="profile"),
|
||||
path("accounts/profile/<str:slug>/", views.account_profile, name="account_profile"),
|
||||
|
||||
+70
-9
@@ -1,6 +1,10 @@
|
||||
import secrets
|
||||
|
||||
from django_tables2 import SingleTableMixin
|
||||
from atlas.models import CaseCollection, CidReportAnswer
|
||||
from generic.decorators import user_is_cid_user_manager
|
||||
from generic.filters import UserUserFilter
|
||||
from generic.tables import UserUserTable
|
||||
from generic.views import CidManagerRequiredMixin, get_question_and_content_type
|
||||
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist
|
||||
from django.shortcuts import render, get_object_or_404, redirect
|
||||
@@ -58,7 +62,7 @@ from rapids.views import GenericExamViews as RapidsExamsViews
|
||||
from longs.views import GenericExamViews as LongsExamViews
|
||||
|
||||
from generic.forms import QuestionNoteForm
|
||||
from generic.models import CidUser, QuestionNote, UserGrades, UserProfile
|
||||
from generic.models import CidUser, QuestionNote, Supervisor, UserGrades, UserProfile
|
||||
|
||||
from django_filters.views import FilterView
|
||||
|
||||
@@ -506,6 +510,43 @@ class UserListView(CidManagerRequiredMixin, FilterView):
|
||||
|
||||
filterset_class = UserListFilter
|
||||
|
||||
class UserListTableView(CidManagerRequiredMixin, SingleTableMixin, FilterView):
|
||||
model = User
|
||||
table_class = UserUserTable
|
||||
template_name = "generic/user_view.html"
|
||||
|
||||
filterset_class = UserUserFilter
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
# user = self.request.user
|
||||
|
||||
#filters = {"archive": False, "exam_mode": True}
|
||||
|
||||
#physics_exams = [(i.name, i.pk) for i in PhysicsExam.objects.filter(**filters)]
|
||||
#rapid_exams = [(i.name, i.pk) for i in RapidExam.objects.filter(**filters)]
|
||||
#sba_exams = [(i.name, i.pk) for i in SbasExam.objects.filter(**filters)]
|
||||
#longs_exams = [(i.name, i.pk) for i in LongExam.objects.filter(**filters)]
|
||||
#anatomy_exams = [(i.name, i.pk) for i in AnatomyExam.objects.filter(**filters)]
|
||||
#casecollection_exams = [
|
||||
# (i.name, i.pk)
|
||||
# for i in CaseCollection.objects.filter(archive=False, collection_type__gt=0)
|
||||
#]
|
||||
|
||||
#context["physics_exams"] = physics_exams
|
||||
#context["rapid_exams"] = rapid_exams
|
||||
#context["sba_exams"] = sba_exams
|
||||
#context["longs_exams"] = longs_exams
|
||||
#context["anatomy_exams"] = anatomy_exams
|
||||
#context["casecollection_exams"] = casecollection_exams
|
||||
|
||||
#cid_user_groups = [
|
||||
# (i.name, i.pk) for i in CidUserGroup.objects.filter(archive=False)
|
||||
#]
|
||||
|
||||
#context["cid_user_groups"] = cid_user_groups
|
||||
return context
|
||||
|
||||
|
||||
class UpdateUserView(CidManagerRequiredMixin, UpdateView):
|
||||
model = User
|
||||
@@ -523,14 +564,12 @@ class UpdateUserView(CidManagerRequiredMixin, UpdateView):
|
||||
class UpdateUserProfileView(CidManagerRequiredMixin, UpdateView):
|
||||
model = UserProfile
|
||||
fields = [
|
||||
"supervisor_name",
|
||||
"supervisor_email",
|
||||
"supervisor",
|
||||
"grade",
|
||||
"registration_number",
|
||||
"peninsula_trainee",
|
||||
] # Keep listing whatever fields
|
||||
template_name = "user_update.html"
|
||||
template_name = "user_update_profile.html"
|
||||
slug_field = "user__username"
|
||||
slug_url_kwarg = "slug"
|
||||
|
||||
@@ -571,6 +610,21 @@ class UpdateUserProfileView(CidManagerRequiredMixin, UpdateView):
|
||||
# def get(self, request, *args, **kwargs):
|
||||
# return self.post(request, *args, **kwargs)
|
||||
|
||||
@user_is_cid_user_manager
|
||||
def accounts_check_users(request):
|
||||
if request.method == "POST":
|
||||
users = json.loads(request.POST.get("user_list"))
|
||||
|
||||
existing_users = []
|
||||
|
||||
for email in users:
|
||||
if User.objects.filter(username=email).exists():
|
||||
existing_users.append(email)
|
||||
|
||||
return JsonResponse({"users": existing_users})
|
||||
|
||||
return
|
||||
|
||||
|
||||
@user_is_cid_user_manager
|
||||
def accounts_bulk_create(request):
|
||||
@@ -610,13 +664,20 @@ def accounts_bulk_create(request):
|
||||
|
||||
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 "supervisor_email" in user and "supervisor_name" in user:
|
||||
s, created = Supervisor.objects.get_or_create(email=user["supervisor_email"], name=user["supervisor_name"])
|
||||
|
||||
if created:
|
||||
s.save()
|
||||
|
||||
user_profile.supervisor = s
|
||||
|
||||
|
||||
if "grade" in user:
|
||||
if not user["grade"].startswith("ST"):
|
||||
user["grade"] = f"ST{user['grade']}"
|
||||
|
||||
|
||||
grade = UserGrades.objects.get(name=user["grade"])
|
||||
user_profile.grade = grade
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{% block content %}
|
||||
{% if created_users %}
|
||||
<div class="alert alert-success">
|
||||
The follow users have been created: {{created_users}}
|
||||
The following users have been created: {{created_users}}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@@ -26,13 +26,16 @@
|
||||
<table>
|
||||
|
||||
<tr><th>First name</th><th>Last name</th><th>Email</th><th>Grade</th><th>Supervisor</th><th>Supervisor email</th></tr>
|
||||
<tr><td>name 1</td><td>last name 1</td><td>email 1</td><td>grade 1</td><td>supervisor 1</td><td>Supervisor email 1</td></tr>
|
||||
<tr><td>name 1</td><td>last name 1</td><td>email1@email.com</td><td>grade 1</td><td>supervisor 1</td><td>Supervisor@email.com</td></tr>
|
||||
<tr><td>name 2</td><td>last name 2</td><td>email2@email.com</td><td>grade 2</td><td>supervisor 2</td><td>Supervisor2@email.com</td></tr>
|
||||
</table>
|
||||
|
||||
|
||||
On your spreadsheet then "copy" the data (not including header), come to this page, put focus on the <textarea> box and "paste" the text in. In some instance (large data sets) this might take a couple of seconds.
|
||||
Once there simply click the button and check the users that will be created below.
|
||||
|
||||
</p>
|
||||
<p>Please note users created this way bypass some of the validations so check details such as email addresses are correct</p>
|
||||
<textarea id="csv" placeholder="Paste users content here" style="width: 300px; height: 100px;"></textarea><br/>
|
||||
<input type="button" value="Load Data" onclick="createTable()" >
|
||||
|
||||
@@ -70,12 +73,13 @@
|
||||
|
||||
// Loop over the rows
|
||||
|
||||
var elements = ["first_name", "last_name", "grade", "email", "supervisor_name", "supervisor_email"];
|
||||
var elements = ["first_name", "last_name", "email", "grade", "supervisor_name", "supervisor_email"];
|
||||
var users = [];
|
||||
|
||||
$("#users-list").empty();
|
||||
$("#users-list").append(`The following users will be created. "undefined" fields will be left blank. Emails will be used as usernames.`);
|
||||
$("#users-list").append(`The following users will be created. "undefined" fields will be left blank. Emails will be used as usernames. Supervisors will be created automatically if required.`);
|
||||
|
||||
var emails = [];
|
||||
for (i=0; i<excelRow.length - 1; i++) {
|
||||
//users[i] = {};
|
||||
user = {};
|
||||
@@ -96,10 +100,16 @@
|
||||
}
|
||||
myTbody.appendChild(myRow);
|
||||
users.push(user)
|
||||
emails.push(user.email)
|
||||
$("#users-list").append(`<li>Name: ${user.first_name} ${user.last_name}<br/>Email: ${user.email}<br/>Grade: ${user.grade}<br/>Supervisor: ${user.supervisor_name}<br/>Supervisor email: ${user.supervisor_email}</li>`)
|
||||
}
|
||||
myTable.appendChild(myTbody);
|
||||
|
||||
$.post("{% url 'accounts_check_users' %}", { csrfmiddlewaretoken: "{{ csrf_token }}",
|
||||
user_list: JSON.stringify(emails) }, function(data) {
|
||||
console.log("Existing users", data)
|
||||
})
|
||||
|
||||
$("#users-list").append(`${users.length} users to create.`)
|
||||
|
||||
$("#user-list-json").val(JSON.stringify(users));
|
||||
|
||||
@@ -16,10 +16,6 @@
|
||||
<div>
|
||||
Grade: {{ user.userprofile.grade }}
|
||||
</div>
|
||||
<div style="border:1px dashed red">
|
||||
Supervisor: {{ user.userprofile.supervisor_name }}<br/>
|
||||
Supervisor Email: {{ user.userprofile.supervisor_email }}<br/>
|
||||
</div>
|
||||
<div>
|
||||
Supervisor: {{ user.userprofile.supervisor }}<br/>
|
||||
</div>
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
{% for list_user in object_list %}
|
||||
<li><span class="username">Username: <a href="{% url 'account_profile' list_user.username %}">{{ list_user.username }}</a></span>
|
||||
<span class="name">Name: {{list_user.first_name}} {{list_user.last_name}}</span>
|
||||
{% if list_user.userprofile.grade %}<span class="grade">Grade: {{list_user.userprofile.grade}}</span>{% endif %} Supervisor: {{list_user.userprofile.supervisor_name}} [{{list_user.userprofile.supervisor_email}}]
|
||||
<br/> Registration number: {{list_user.registration_number}}
|
||||
{% if list_user.userprofile.grade %}<span class="grade">Grade: {{list_user.userprofile.grade}}</span>{% endif %} Supervisor: {{list_user.userprofile.supervisor}}
|
||||
<br/> Registration number: {{list_user.userprofile.registration_number}}
|
||||
<button class="small-url-button"><a href="{% url 'account_update' list_user.username %}">Edit user</a></button>
|
||||
<button class="small-url-button"><a href="{% url 'account_profile_update' list_user.username %}">Edit profile</a></button>
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
{% block content %}
|
||||
<h2>Editing user: {{object.username}}</h2>
|
||||
This form allows you to edit the users name and email address. More details (such as grade / supervisor / etc...) can be changed <a href="{% url 'account_profile_update' object.username %}">here</a>
|
||||
<form method="post">{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit" value="Update">
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
{% extends 'generic/base.html' %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Editing user: {{object.username}}</h2>
|
||||
This form allows you to edit additional user details. Name and emails can be edited <a href="{% url 'account_update' object.username %}">here</a>
|
||||
<form method="post">{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit" value="Update">
|
||||
</form>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user