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

-
- {% csrf_token %} - - {{ form.as_table }} -
- -
-{% 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

-
- {% csrf_token %} - - {{ form.as_table }} -
- -
-{% 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

-
- {% csrf_token %} - - {{ form.as_table }} -
- -
-{% 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

-
- {% csrf_token %} - - {{ form.as_table }} -
- -
-{% 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

-
- {% csrf_token %} - - {{ form.as_table }} -
- -
-{% 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. +

+
+ {% csrf_token %} + + {{ form.as_table }} +
+ +
+{% 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 }}

{% csrf_token %}

Are you sure you want to delete the exam "{{ object }}"?