diff --git a/anatomy/templates/anatomy/exam_form.html b/anatomy/templates/anatomy/exam_form.html
deleted file mode 100755
index 0131ad79..00000000
--- a/anatomy/templates/anatomy/exam_form.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{% extends "anatomy/exams.html" %}
-
-{% block js %}
- {{ form.media }}
-{% endblock %}
-
-{% block content %}
-
Add Exam
-
-{% endblock %}
diff --git a/anatomy/views.py b/anatomy/views.py
index 07bc7a01..f80cade5 100644
--- a/anatomy/views.py
+++ b/anatomy/views.py
@@ -805,7 +805,7 @@ class ExamCreate(ExamCreateBase):
form_class = ExamForm
-class ExamUpdate(CheckCanEditMixin, ExamUpdateBase, AuthorOrCheckerRequiredMixin):
+class ExamUpdate(ExamUpdateBase, AuthorOrCheckerRequiredMixin):
model = Exam
form_class = ExamForm
diff --git a/atlas/models.py b/atlas/models.py
index 45205d76..b9aa01ac 100644
--- a/atlas/models.py
+++ b/atlas/models.py
@@ -783,6 +783,9 @@ class CaseCollection(ExamOrCollectionGenericBase):
def get_app_name(self):
return "atlas"
+ def get_base_template(self):
+ return "atlas/base.html"
+
def get_link_headers(self):
return f"{self.get_app_name()}/collection_headers.html"
diff --git a/atlas/templates/atlas/collection_detail.html b/atlas/templates/atlas/collection_detail.html
index 485b814c..1023e6fe 100644
--- a/atlas/templates/atlas/collection_detail.html
+++ b/atlas/templates/atlas/collection_detail.html
@@ -1,6 +1,9 @@
{% extends 'atlas/exams.html' %}
{% block content %}
+{{collection.name}}
+
+{% include 'exam_notes.html' %}
Exam mode: {{collection.exam_mode}}
Publish results: {{collection.publish_results}}
diff --git a/atlas/templates/atlas/collection_headers.html b/atlas/templates/atlas/collection_headers.html
index ac776a7b..d3d443ed 100644
--- a/atlas/templates/atlas/collection_headers.html
+++ b/atlas/templates/atlas/collection_headers.html
@@ -16,7 +16,3 @@
{% endif %}
-
-{{collection.name}}
-
-{% include 'exam_notes.html' %}
diff --git a/generic/views.py b/generic/views.py
index d795a9ae..260c46e6 100644
--- a/generic/views.py
+++ b/generic/views.py
@@ -49,7 +49,7 @@ from generic.decorators import user_is_cid_user_manager
from generic.filters import CidUserFilter, ExaminationFilter
from generic.tables import CidUserExamTable, CidUserTable, ExaminationTable
-from generic.mixins import SuperuserRequiredMixin
+from generic.mixins import CheckCanEditMixin, SuperuserRequiredMixin
import zipfile
from django.core.files.base import ContentFile
@@ -2433,11 +2433,16 @@ class GenericViewBase:
)
-class ExamCloneMixin:
+class ExamCloneMixin():
+ def get_template_names(self) -> list[str]:
+ return "exam_clone_form.html"
+ #return super().get_template_names()
+
+
def get_initial(self):
old_object = get_object_or_404(self.model, pk=self.kwargs["exam_id"])
- if self.request.user not in old_object.get_author_objects() and not self.request.user.is_superuser:
+ if not old_object.check_user_can_edit(self.request.user):
raise PermissionDenied() # or Http404
initial_data = model_to_dict(old_object, exclude=["id"])
@@ -2458,8 +2463,18 @@ class ExamCloneMixin:
self.exam_questions = list(questions)
self.author = list(authors)
+ self.old_object = old_object
+
return initial_data
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+
+ context["can_edit"] = self.old_object.check_user_can_edit(self.request.user)
+ context["exam"] = self.old_object
+
+ return context
+
def form_valid(self, form):
object = form.save()
# Reapply these otherwise they get lost?
@@ -3158,7 +3173,7 @@ class ExamCreateBase(RevisionMixin, LoginRequiredMixin, CreateView):
return kwargs
-class ExamUpdateBase(RevisionMixin, LoginRequiredMixin, UpdateView):
+class ExamUpdateBase(RevisionMixin, CheckCanEditMixin, LoginRequiredMixin, UpdateView):
template_name = "exam_update_form.html"
def form_valid(self, form):
@@ -3175,7 +3190,7 @@ class ExamUpdateBase(RevisionMixin, LoginRequiredMixin, UpdateView):
return kwargs
-class ExamDeleteBase(RevisionMixin, DeleteView):
+class ExamDeleteBase(RevisionMixin, CheckCanEditMixin, DeleteView):
template_name = "exam_confirm_delete.html"
def get_success_url(self) -> str:
diff --git a/longs/templates/longs/exam_form.html b/longs/templates/longs/exam_form.html
deleted file mode 100755
index 50f662ed..00000000
--- a/longs/templates/longs/exam_form.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{% extends "longs/exams.html" %}
-
-{% block js %}
- {{ form.media }}
-{% endblock %}
-
-{% block content %}
-Add Exam
-
-{% endblock %}
diff --git a/longs/views.py b/longs/views.py
index 3cd2fc31..04182ab9 100755
--- a/longs/views.py
+++ b/longs/views.py
@@ -1130,7 +1130,7 @@ class ExamCreate(ExamCreateBase):
form_class = ExamForm
-class ExamUpdate(CheckCanEditMixin, ExamUpdateBase, AuthorOrCheckerRequiredMixin):
+class ExamUpdate(ExamUpdateBase, AuthorOrCheckerRequiredMixin):
model = Exam
form_class = ExamForm
diff --git a/physics/templates/physics/exam_form.html b/physics/templates/physics/exam_form.html
deleted file mode 100755
index 30eb27e1..00000000
--- a/physics/templates/physics/exam_form.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{% extends "physics/exams.html" %}
-
-{% block js %}
- {{ form.media }}
-{% endblock %}
-
-{% block content %}
-Add Exam
-
-{% endblock %}
diff --git a/physics/views.py b/physics/views.py
index 5a56127c..f453c615 100644
--- a/physics/views.py
+++ b/physics/views.py
@@ -339,7 +339,7 @@ class ExamCreate(ExamCreateBase):
form_class = ExamForm
-class ExamUpdate(CheckCanEditMixin, ExamUpdateBase, AuthorOrCheckerRequiredMixin):
+class ExamUpdate(ExamUpdateBase, AuthorOrCheckerRequiredMixin):
model = Exam
form_class = ExamForm
diff --git a/rapids/templates/rapids/exam_form.html b/rapids/templates/rapids/exam_form.html
deleted file mode 100755
index 9901ffac..00000000
--- a/rapids/templates/rapids/exam_form.html
+++ /dev/null
@@ -1,17 +0,0 @@
-{% extends "rapids/base.html" %}
-
-{% block js %}
- {{ form.media }}
-{% endblock %}
-
-{% block content %}
-
- Add Exam
-
-{% endblock %}
diff --git a/rapids/views.py b/rapids/views.py
index 5afb8c8c..a4d16879 100755
--- a/rapids/views.py
+++ b/rapids/views.py
@@ -745,7 +745,7 @@ class ExamCreate(ExamCreateBase):
form_class = ExamForm
-class ExamUpdate(CheckCanEditMixin, ExamUpdateBase, AuthorOrCheckerRequiredMixin):
+class ExamUpdate(ExamUpdateBase, AuthorOrCheckerRequiredMixin):
model = Exam
form_class = ExamForm
diff --git a/sbas/templates/sbas/exam_form.html b/sbas/templates/sbas/exam_form.html
deleted file mode 100755
index 68d08070..00000000
--- a/sbas/templates/sbas/exam_form.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{% extends "sbas/exams.html" %}
-
-{% block js %}
- {{ form.media }}
-{% endblock %}
-
-{% block content %}
-Add Exam
-
-{% endblock %}
diff --git a/sbas/urls.py b/sbas/urls.py
index 7f187ea7..6bc93db6 100644
--- a/sbas/urls.py
+++ b/sbas/urls.py
@@ -55,7 +55,7 @@ urlpatterns = [
path("exam//clone", views.ExamClone.as_view(), name="exam_clone"),
path("exam//clone2", views.exam_clone2, name="exam_clone2"),
path("exam/available", views.active_exams, name="active_exams"),
- path("exam/create", views.ExamUpdate.as_view(), name="exam_create"),
+ path("exam/create", views.ExamCreate.as_view(), name="exam_create"),
path("exam//update", views.ExamUpdate.as_view(), name="exam_update"),
path("exam//delete", views.ExamDelete.as_view(), name="exam_delete"),
# path("exam/json/", views.exam_json, name="exam_json"),
diff --git a/sbas/views.py b/sbas/views.py
index ddda217d..cee02d3b 100644
--- a/sbas/views.py
+++ b/sbas/views.py
@@ -402,7 +402,7 @@ class ExamCreate(ExamCreateBase):
form_class = ExamForm
-class ExamUpdate(CheckCanEditMixin, ExamUpdateBase, AuthorOrCheckerRequiredMixin):
+class ExamUpdate(ExamUpdateBase, AuthorOrCheckerRequiredMixin):
model = Exam
form_class = ExamForm
diff --git a/templates/exam_clone_form.html b/templates/exam_clone_form.html
new file mode 100644
index 00000000..713c035e
--- /dev/null
+++ b/templates/exam_clone_form.html
@@ -0,0 +1,27 @@
+{% extends view.model.app_name|add:"/exams.html" %}
+
+{% block js %}
+ {{ form.media }}
+{% endblock %}
+
+{% block navigation %}
+{{ block.super }}
+ {% include exam.get_link_headers %}
+{% endblock navigation %}
+
+{% block content %}
+
+ Cloning Exam: {{exam}}
+
+ This will create a new exam with the same settings, questions and answers as the original exam.
+ Candidate groups and candidates will not be cloned.
+
+
+{% endblock %}
+
diff --git a/templates/exam_confirm_delete.html b/templates/exam_confirm_delete.html
index 169815b2..2f55de70 100644
--- a/templates/exam_confirm_delete.html
+++ b/templates/exam_confirm_delete.html
@@ -1,7 +1,12 @@
-{% extends 'base.html' %}
+{% extends object.get_base_template %}
+{% block navigation %}
+{{ block.super }}
+ {% include object.get_link_headers %}
+{% endblock navigation %}
{% block content %}
+Delete Exam: {{ object }}