add bulk edit grades
This commit is contained in:
@@ -1,11 +1,16 @@
|
||||
from django.core.exceptions import PermissionDenied
|
||||
|
||||
|
||||
def user_is_cid_user_manager(function):
|
||||
def wrap(request, *args, **kwargs):
|
||||
if request.user.groups.filter(name='cid_user_manager').exists() or request.user.is_superuser:
|
||||
if (
|
||||
request.user.groups.filter(name="cid_user_manager").exists()
|
||||
or request.user.is_superuser
|
||||
):
|
||||
return function(request, *args, **kwargs)
|
||||
else:
|
||||
raise PermissionDenied
|
||||
|
||||
wrap.__doc__ = function.__doc__
|
||||
wrap.__name__ = function.__name__
|
||||
return wrap
|
||||
return wrap
|
||||
|
||||
@@ -7,18 +7,18 @@
|
||||
{% 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>
|
||||
<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>
|
||||
<div id="table-div">
|
||||
<span id="manage-span">
|
||||
{% render_table table %}
|
||||
</span>
|
||||
@@ -31,7 +31,21 @@
|
||||
<summary>
|
||||
Bulk edit
|
||||
</summary>
|
||||
<button>Delete supervisors</button>
|
||||
<div id="htmx-info"></div>
|
||||
<div id="htmx-options"></div>
|
||||
<button id="bulk-delete-supervisors-button"
|
||||
title="Deletes the supervisors of all selected users"
|
||||
hx-post="{% url 'generic:users_bulk_delete_supervisors' %}"
|
||||
hx-include="[name='selection']"
|
||||
hx-confirm="This will delete supervisors from all selected users, are you sure you wish to continue?"
|
||||
hx-target="#htmx-info"
|
||||
>Delete supervisors</button>
|
||||
<button id="bulk-edit-grade-button"
|
||||
hx-post="{% url 'generic:users_bulk_edit_grade' %}"
|
||||
hx-include="[name='selection']"
|
||||
hx-target="#htmx-options"
|
||||
|
||||
>Edit grade</button>
|
||||
</details>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
+14
-1
@@ -77,6 +77,8 @@ urlpatterns = [
|
||||
path(
|
||||
"cids/group/create", views.CidUserGroupCreate.as_view(), name="cid_group_create"
|
||||
),
|
||||
path("user/bulk_delete_supervisors/", views.users_bulk_delete_supervisors, name="users_bulk_delete_supervisors"),
|
||||
path("user/bulk_edit_grade/", views.users_bulk_edit_grade, name="users_bulk_edit_grade"),
|
||||
path("user/group/", views.user_group_view, name="user_group_view"),
|
||||
path("user/group/all", views.user_group_view_all, name="user_group_view_all"),
|
||||
path("user/group/<int:group_id>/", views.user_group_view_detail, name="user_group_detail"),
|
||||
@@ -246,16 +248,27 @@ def generic_exam_urls(generic_exam_view: GenericExamViews):
|
||||
generic_exam_view.exam_json_cid_unbased,
|
||||
name="exam_json_cid_unbased",
|
||||
),
|
||||
# These are a little more ambiguous than ideal
|
||||
path(
|
||||
"exam/json/<int:pk>/<int:sk>",
|
||||
generic_exam_view.exam_question_json,
|
||||
name="exam_question_json_unbased",
|
||||
name="exam_question_json",
|
||||
),
|
||||
path(
|
||||
"exam/json/<int:pk>/<int:sk>/unbased",
|
||||
generic_exam_view.exam_question_json_unbased,
|
||||
name="exam_question_json_unbased",
|
||||
),
|
||||
path(
|
||||
"exam/json/<int:pk>/<int:cid>/<str:passcode>/<int:sk>",
|
||||
generic_exam_view.exam_question_json_cid,
|
||||
name="exam_question_json_cid",
|
||||
),
|
||||
path(
|
||||
"exam/json/<int:pk>/<int:cid>/<str:passcode>/<int:sk>/unbased",
|
||||
generic_exam_view.exam_question_json_unbased_cid,
|
||||
name="exam_question_json_unbased_cid",
|
||||
),
|
||||
path(
|
||||
"exam/json/<int:pk>/recreate",
|
||||
generic_exam_view.exam_json_recreate,
|
||||
|
||||
+188
-39
@@ -58,7 +58,19 @@ from .forms import (
|
||||
UserUserGroupForm,
|
||||
)
|
||||
|
||||
from .models import CidUser, CidUserGroup, ExamBase, ExamUserStatus, Examination, QuestionNote, Supervisor, UserGrades, UserProfile, UserUserGroup, get_next_cid
|
||||
from .models import (
|
||||
CidUser,
|
||||
CidUserGroup,
|
||||
ExamBase,
|
||||
ExamUserStatus,
|
||||
Examination,
|
||||
QuestionNote,
|
||||
Supervisor,
|
||||
UserGrades,
|
||||
UserProfile,
|
||||
UserUserGroup,
|
||||
get_next_cid,
|
||||
)
|
||||
|
||||
from rapids.models import Rapid as RapidQuestion
|
||||
from rapids.models import Exam as RapidExam
|
||||
@@ -355,6 +367,7 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
|
||||
self.ExamFilter = ExamFilter
|
||||
|
||||
# TODO: these may be better implemented as decorators
|
||||
def check_user_access(self, user: User, exam_id: int = None):
|
||||
"""Check if a user should be able to access a view
|
||||
|
||||
@@ -479,9 +492,7 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
|
||||
exam = get_object_or_404(self.Exam, pk=pk)
|
||||
|
||||
exam.archive = (
|
||||
True if request.POST.get("archive") == "true" else False
|
||||
)
|
||||
exam.archive = True if request.POST.get("archive") == "true" else False
|
||||
print(f"{exam.archive=}")
|
||||
exam.save()
|
||||
data = {
|
||||
@@ -842,7 +853,7 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
"can_edit": can_edit,
|
||||
"notes": notes,
|
||||
"app_name": self.app_name,
|
||||
"candidate_count": (cid_candidates, users_candidates)
|
||||
"candidate_count": (cid_candidates, users_candidates),
|
||||
},
|
||||
)
|
||||
|
||||
@@ -885,7 +896,7 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
|
||||
Returns:
|
||||
_type_: _description_
|
||||
"""
|
||||
"""
|
||||
exam = get_object_or_404(self.Exam, pk=exam_id)
|
||||
|
||||
# if not request.user.groups.filter(name="cid_user_manager").exists():
|
||||
@@ -1020,25 +1031,26 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
else:
|
||||
statuses = exam.exam_user_status.all()
|
||||
|
||||
return render(request, "exam_user_status.html", {"exam": exam, "statuses": statuses})
|
||||
return render(
|
||||
request, "exam_user_status.html", {"exam": exam, "statuses": statuses}
|
||||
)
|
||||
|
||||
#if not self.check_user_access(request.user, pk):
|
||||
# if not self.check_user_access(request.user, pk):
|
||||
# raise PermissionDenied
|
||||
|
||||
#q, content_type = get_question_and_content_type(self.question_type)
|
||||
# q, content_type = get_question_and_content_type(self.question_type)
|
||||
|
||||
## Get active notes for type
|
||||
#statuses = ExamUserStatus.objects.filter(
|
||||
# statuses = ExamUserStatus.objects.filter(
|
||||
# content_type=content_type, object_id__in=pk
|
||||
#)
|
||||
# )
|
||||
|
||||
#return statuses
|
||||
# return statuses
|
||||
|
||||
@method_decorator(login_required)
|
||||
def exam_json_edit(self, request, pk):
|
||||
if request.method == "POST":
|
||||
|
||||
|
||||
if request.user.groups.filter(name="cid_user_manager").exists():
|
||||
# This may give more permissions than we actually want
|
||||
pass
|
||||
@@ -1306,7 +1318,14 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
},
|
||||
)
|
||||
|
||||
def active_exams(self, request: HttpRequest, json: bool=True, based: bool=True, cid: int=None, passcode: str=None):
|
||||
def active_exams(
|
||||
self,
|
||||
request: HttpRequest,
|
||||
json: bool = True,
|
||||
based: bool = True,
|
||||
cid: int = None,
|
||||
passcode: str = None,
|
||||
):
|
||||
exams = self.Exam.objects.filter(archive=False)
|
||||
|
||||
active_exams = {"exams": []}
|
||||
@@ -1321,7 +1340,9 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
exam: ExamBase
|
||||
for exam in exams:
|
||||
if exam.active or self.check_user_access(request.user, exam.pk):
|
||||
print(f"{exam.app_name=}, {exam.name=}, {cid=}, {passcode=}, {request.user=}")
|
||||
print(
|
||||
f"{exam.app_name=}, {exam.name=}, {cid=}, {passcode=}, {request.user=}"
|
||||
)
|
||||
if exam.exam_mode and not exam.check_cid_user(
|
||||
cid, passcode, request=request, user_id=request.user.pk
|
||||
):
|
||||
@@ -1333,7 +1354,9 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
else:
|
||||
creation_time = "None"
|
||||
|
||||
url = request.build_absolute_uri(exam.get_json_url(cid=cid, passcode=passcode))
|
||||
url = request.build_absolute_uri(
|
||||
exam.get_json_url(cid=cid, passcode=passcode)
|
||||
)
|
||||
# hacky
|
||||
if not based:
|
||||
url = url + "/unbased"
|
||||
@@ -1544,7 +1567,6 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
return JsonResponse({"success": True, "question_count": n})
|
||||
return JsonResponse({"success": False, "error": "Invalid data"})
|
||||
|
||||
|
||||
def exam_json_cid(self, request, pk, cid, passcode):
|
||||
return self.exam_json(request, pk, cid, passcode)
|
||||
|
||||
@@ -1578,7 +1600,9 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
cid_user = CidUser.objects.get(cid=cid)
|
||||
else:
|
||||
cid_user = None
|
||||
exam.exam_user_status.create(cid_user=cid_user, user_user=user, status="downloaded")
|
||||
exam.exam_user_status.create(
|
||||
cid_user=cid_user, user_user=user, status="downloaded"
|
||||
)
|
||||
|
||||
path = "{0}{1}/exam/{2}.json".format(settings.MEDIA_ROOT, self.app_name, pk)
|
||||
url = "{0}{1}/exam/{2}.json".format(settings.MEDIA_URL, self.app_name, pk)
|
||||
@@ -1629,6 +1653,14 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
if not exam.active and not self.check_user_access(request.user, pk):
|
||||
raise Http404("No available exam")
|
||||
|
||||
# Check access for users
|
||||
if request.user.is_anonymous:
|
||||
user_id = None
|
||||
else:
|
||||
user_id = request.user.pk
|
||||
if not exam.check_cid_user(cid, passcode, request, user_id):
|
||||
raise Http404("No available exam")
|
||||
|
||||
time = datetime.now()
|
||||
|
||||
exam_json = exam.get_exam_json(based=False)
|
||||
@@ -1642,17 +1674,30 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
cid_user = CidUser.objects.get(cid=cid)
|
||||
else:
|
||||
cid_user = None
|
||||
exam.exam_user_status.create(cid_user=cid, user_user=user, status="downloaded", extra="unbased")
|
||||
exam.exam_user_status.create(
|
||||
cid_user=cid, user_user=user, status="downloaded", extra="unbased"
|
||||
)
|
||||
|
||||
return JsonResponse(exam_json)
|
||||
|
||||
def exam_question_json(self, request, pk, sk):
|
||||
def exam_question_json_cid(self, request, pk, sk, cid, passcode):
|
||||
return self.exam_question_json(request, pk, sk, cid, passcode)
|
||||
|
||||
def exam_question_json(self, request, pk, sk, cid=None, passcode=None):
|
||||
question = get_object_or_404(self.Question, pk=sk)
|
||||
exam = get_object_or_404(self.Exam, pk=pk)
|
||||
|
||||
if not exam.active and not self.check_user_access(request.user, pk):
|
||||
raise Http404("No available exam")
|
||||
|
||||
# Check access for users
|
||||
if request.user.is_anonymous:
|
||||
user_id = None
|
||||
else:
|
||||
user_id = request.user.pk
|
||||
if not exam.check_cid_user(cid, passcode, request, user_id):
|
||||
raise Http404("No available exam")
|
||||
|
||||
if request.GET.get("_"):
|
||||
base_url = redirect("{}:question_json".format(self.app_name), pk=sk)
|
||||
query_string = urllib.parse.urlencode({"_": request.GET.get("_")})
|
||||
@@ -1661,6 +1706,9 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
|
||||
return redirect("{}:question_json".format(self.app_name), pk=sk)
|
||||
|
||||
def exam_question_json_unbased_cid(self, request, pk, sk, cid, passcode):
|
||||
return self.exam_question_json_unbased(request, pk, sk, cid, passcode)
|
||||
|
||||
def exam_question_json_unbased(self, request, pk, sk):
|
||||
question = get_object_or_404(self.Question, pk=sk)
|
||||
exam = get_object_or_404(self.Exam, pk=pk)
|
||||
@@ -1815,7 +1863,6 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
|
||||
cached_scores = True
|
||||
|
||||
|
||||
valid_cid_users = set(exam.valid_cid_users.all().values_list("cid", flat=True))
|
||||
valid_user_users = set(exam.valid_user_users.all().values_list("pk", flat=True))
|
||||
|
||||
@@ -2242,7 +2289,6 @@ class CidUserView(CidManagerRequiredMixin, SingleTableMixin, FilterView):
|
||||
return context
|
||||
|
||||
|
||||
|
||||
@user_is_cid_user_manager
|
||||
def cid_group_view(request):
|
||||
groups = CidUserGroup.objects.filter(archive=False)
|
||||
@@ -2253,6 +2299,7 @@ def cid_group_view(request):
|
||||
{"groups": groups},
|
||||
)
|
||||
|
||||
|
||||
@user_is_cid_user_manager
|
||||
def cid_group_view_detail(request, group_id):
|
||||
group = get_object_or_404(CidUserGroup, pk=group_id)
|
||||
@@ -2265,6 +2312,7 @@ def cid_group_view_detail(request, group_id):
|
||||
{"group": group, "users": users, "group_type": "cid"},
|
||||
)
|
||||
|
||||
|
||||
@user_is_cid_user_manager
|
||||
def cid_group_view_all(request):
|
||||
groups = CidUserGroup.objects.filter()
|
||||
@@ -2275,11 +2323,12 @@ def cid_group_view_all(request):
|
||||
{"groups": groups, "view_all": True},
|
||||
)
|
||||
|
||||
|
||||
@user_is_cid_user_manager
|
||||
def user_group_view_detail(request, group_id):
|
||||
group = get_object_or_404(UserUserGroup, pk=group_id)
|
||||
|
||||
users = group.users.filter() # Filter inactive users?
|
||||
users = group.users.filter() # Filter inactive users?
|
||||
|
||||
return render(
|
||||
request,
|
||||
@@ -2287,6 +2336,89 @@ def user_group_view_detail(request, group_id):
|
||||
{"group": group, "users": users, "group_type": "user"},
|
||||
)
|
||||
|
||||
|
||||
@user_is_cid_user_manager
|
||||
def users_bulk_delete_supervisors(request):
|
||||
if "selection" in request.POST:
|
||||
selected_users = request.POST.getlist("selection")
|
||||
user_models = User.objects.filter(id__in=selected_users)
|
||||
|
||||
for u in user_models:
|
||||
u.userprofile.supervisor = None
|
||||
u.save()
|
||||
|
||||
modified_users = ",".join([user.username for user in user_models])
|
||||
|
||||
return HttpResponse(
|
||||
f"Supervisors removed from {modified_users}. Refresh page to see update",
|
||||
content_type="text/plain",
|
||||
)
|
||||
|
||||
else:
|
||||
return HttpResponse("No users selected", content_type="text/plain")
|
||||
|
||||
|
||||
@user_is_cid_user_manager
|
||||
def users_bulk_edit_grade(request):
|
||||
|
||||
if request.htmx.trigger == "bulk-edit-grade-button":
|
||||
user_grades = UserGrades.objects.all()
|
||||
|
||||
html = "".join(
|
||||
[
|
||||
f"""<button class='change-grade-button' name='add-grade--{grade.id}'
|
||||
hx-post="{reverse('generic:users_bulk_edit_grade')}"
|
||||
hx-include="[name='selection']"
|
||||
hx-confirm="This will modify grades of all selected users, are you sure you wish to continue?"
|
||||
hx-target="#htmx-info"
|
||||
>{grade.name}</button>"""
|
||||
for grade in user_grades
|
||||
]
|
||||
)
|
||||
# TODO: work out how to actually use hyperscript
|
||||
html = (
|
||||
html
|
||||
+ "<button _='on click for el in .change-grade-button remove el end then remove me'>Cancel</button>"
|
||||
)
|
||||
|
||||
return HttpResponse(html, content_type="text/html")
|
||||
elif request.htmx.trigger_name.startswith("add-grade"):
|
||||
selected_users = request.POST.getlist("selection")
|
||||
|
||||
if not selected_users:
|
||||
return HttpResponse("No users selected", content_type="text/html")
|
||||
user_models = User.objects.filter(id__in=selected_users)
|
||||
|
||||
# u: User
|
||||
for u in user_models:
|
||||
u.userprofile.grade_id = request.htmx.trigger_name.split("--")[-1]
|
||||
u.save()
|
||||
return HttpResponse("Grades update", content_type="text/html")
|
||||
else:
|
||||
return HttpResponse("Error", content_type="text/html")
|
||||
|
||||
|
||||
@user_is_cid_user_manager
|
||||
def users_bulk_delete_supervisors(request):
|
||||
if "selection" in request.POST:
|
||||
selected_users = request.POST.getlist("selection")
|
||||
user_models = User.objects.filter(id__in=selected_users)
|
||||
|
||||
for u in user_models:
|
||||
u.userprofile.supervisor = None
|
||||
u.save()
|
||||
|
||||
modified_users = ",".join([user.username for user in user_models])
|
||||
|
||||
return HttpResponse(
|
||||
f"Supervisors removed from {modified_users}. Refresh page to see update",
|
||||
content_type="text/plain",
|
||||
)
|
||||
|
||||
else:
|
||||
return HttpResponse("No users selected", content_type="text/plain")
|
||||
|
||||
|
||||
@user_is_cid_user_manager
|
||||
def user_group_view(request):
|
||||
groups = UserUserGroup.objects.filter(archive=False)
|
||||
@@ -2391,10 +2523,12 @@ def candidate_email_results(request, cid, resend=False):
|
||||
def candidate_email_results_resend(request, cid, resend=True):
|
||||
return candidate_email_results(request, cid, resend=True)
|
||||
|
||||
|
||||
@user_is_cid_user_manager
|
||||
def create_cid_email(request):
|
||||
pass
|
||||
|
||||
|
||||
@user_is_cid_user_manager
|
||||
def manage_cid_users(request):
|
||||
if request.method == "POST":
|
||||
@@ -2410,7 +2544,6 @@ def manage_cid_users(request):
|
||||
|
||||
emails = json.loads(request.POST.get("emails"))
|
||||
|
||||
|
||||
number_to_create = int(request.POST.get("number_to_create"))
|
||||
|
||||
add_group = request.POST.get("add_group")
|
||||
@@ -2513,13 +2646,15 @@ def manage_cid_users(request):
|
||||
validate_email(email)
|
||||
except ValidationError as e:
|
||||
invalid_emails.append(f"Invalid email: {email}")
|
||||
|
||||
|
||||
print(f"Email list {email_list}")
|
||||
if not email_list:
|
||||
return JsonResponse({"status": "fail", "details": "No valid emails"})
|
||||
if invalid_emails or not email_list:
|
||||
e = "<br/>".join(invalid_emails)
|
||||
return JsonResponse({"status": "fail", "details": f"Unable to create users<hr>{e}"})
|
||||
return JsonResponse(
|
||||
{"status": "fail", "details": f"Unable to create users<hr>{e}"}
|
||||
)
|
||||
|
||||
for e in email_list:
|
||||
passcode = "".join(random.choices(string.ascii_uppercase, k=4))
|
||||
@@ -2578,16 +2713,18 @@ class CidUserUpdate(CidManagerRequiredMixin, UpdateView):
|
||||
model = CidUser
|
||||
form_class = CidUserForm
|
||||
|
||||
|
||||
class CidUserExamUpdate(CidManagerRequiredMixin, UpdateView):
|
||||
model = CidUser
|
||||
form_class = CidUserExamForm
|
||||
template_name = "generic/ciduserexam_form.html"
|
||||
|
||||
#def get_context_data(self, *args, **kwargs):
|
||||
# def get_context_data(self, *args, **kwargs):
|
||||
# context = super().get_context_data(**kwargs)
|
||||
# context["test"] = "HELLO"
|
||||
# return context
|
||||
|
||||
|
||||
class CidUserGroupDelete(RevisionMixin, CidManagerRequiredMixin, DeleteView):
|
||||
model = CidUserGroup
|
||||
template_name = "confirm_delete.html"
|
||||
@@ -2672,16 +2809,18 @@ class ExamDeleteBase(RevisionMixin, DeleteView):
|
||||
def exam_inactive(request, context):
|
||||
return render(request, "exam_inactive.html", context)
|
||||
|
||||
#class UserUserCreate(CidManagerRequiredMixin, CreateView):
|
||||
|
||||
# class UserUserCreate(CidManagerRequiredMixin, CreateView):
|
||||
# model = User
|
||||
# form_class = UserUserForm
|
||||
# template_name: str = "generic/user_creation_form.html"
|
||||
#
|
||||
# success_url = reverse_lazy("accounts_list")
|
||||
|
||||
|
||||
def create_user(request, context=None):
|
||||
# if this is a POST request we need to process the form data
|
||||
if request.method == 'POST':
|
||||
if request.method == "POST":
|
||||
# create a form instance and populate it with data from the request:
|
||||
form = UserUserForm(request.POST)
|
||||
# check whether it's valid:
|
||||
@@ -2692,20 +2831,22 @@ def create_user(request, context=None):
|
||||
"first_name": request.POST["first_name"],
|
||||
"last_name": request.POST["last_name"],
|
||||
"email": request.POST["username"],
|
||||
"password": secrets.token_hex(nbytes=16)
|
||||
"password": secrets.token_hex(nbytes=16),
|
||||
}
|
||||
|
||||
|
||||
new_user = User.objects.create_user(**user_dict)
|
||||
except Exception as error:
|
||||
errors = f"Unable to create account: {error}"
|
||||
return render(request, 'generic/user_creation_form.html', {'form': form, "errors": errors})
|
||||
return render(
|
||||
request,
|
||||
"generic/user_creation_form.html",
|
||||
{"form": form, "errors": errors},
|
||||
)
|
||||
|
||||
try:
|
||||
|
||||
user_profile = UserProfile.objects.get(user=new_user)
|
||||
user_profile.peninsula_trainee = True
|
||||
|
||||
|
||||
if request.POST["grade"]:
|
||||
grade = UserGrades.objects.get(pk=request.POST["grade"])
|
||||
@@ -2714,12 +2855,16 @@ def create_user(request, context=None):
|
||||
if request.POST["supervisor"]:
|
||||
supervisor = Supervisor.objects.get(pk=request.POST["supervisor"])
|
||||
user_profile.supervisor = supervisor
|
||||
|
||||
|
||||
user_profile.save()
|
||||
|
||||
except Exception as error:
|
||||
errors = f"Unable to create account profile {error}"
|
||||
return render(request, 'generic/user_creation_form.html', {'form': form, "errors": errors})
|
||||
return render(
|
||||
request,
|
||||
"generic/user_creation_form.html",
|
||||
{"form": form, "errors": errors},
|
||||
)
|
||||
|
||||
return HttpResponseRedirect(reverse_lazy("accounts_list"))
|
||||
return reverse_lazy("accounts_list")
|
||||
@@ -2728,7 +2873,8 @@ def create_user(request, context=None):
|
||||
else:
|
||||
form = UserUserForm()
|
||||
|
||||
return render(request, 'generic/user_creation_form.html', {'form': form})
|
||||
return render(request, "generic/user_creation_form.html", {"form": form})
|
||||
|
||||
|
||||
class SupervisorDetail(CidManagerRequiredMixin, DetailView):
|
||||
model = Supervisor
|
||||
@@ -2739,15 +2885,18 @@ class SupervisorDelete(CidManagerRequiredMixin, DeleteView):
|
||||
template_name: str = "confirm_delete.html"
|
||||
success_url = reverse_lazy("generic:supervisor")
|
||||
|
||||
|
||||
class SupervisorUpdate(CidManagerRequiredMixin, UpdateView):
|
||||
model = Supervisor
|
||||
form_class = SupervisorForm
|
||||
#success_url = reverse_lazy("generic:supervisor_detail", kwargs={'pk': self.pk})
|
||||
# success_url = reverse_lazy("generic:supervisor_detail", kwargs={'pk': self.pk})
|
||||
|
||||
|
||||
class SupervisorCreate(CidManagerRequiredMixin, CreateView):
|
||||
model = Supervisor
|
||||
form_class = SupervisorForm
|
||||
#success_url = reverse_lazy("generic:supervisor_detail")
|
||||
# success_url = reverse_lazy("generic:supervisor_detail")
|
||||
|
||||
|
||||
class SupervisorList(CidManagerRequiredMixin, ListView):
|
||||
model = Supervisor
|
||||
model = Supervisor
|
||||
|
||||
Reference in New Issue
Block a user