Add exam collection link to the navigation menu and clean up dropdown toggle
This commit is contained in:
@@ -4709,6 +4709,67 @@ class ExamCollectionClone(CreateView, AuthorRequiredMixin):
|
||||
|
||||
object.author.set(self.author)
|
||||
object.save()
|
||||
|
||||
# Clone exams linked to the original collection into the new one.
|
||||
# For each supported exam app, find exams related to the old collection
|
||||
# and create shallow copies (questions/authors re-applied, but
|
||||
# active/archive/publish flags cleared).
|
||||
if hasattr(self, "initial_object") and self.initial_object:
|
||||
for _label, rel_name, ExamModel in GROUP_TYPES:
|
||||
try:
|
||||
old_exams = list(getattr(self.initial_object, rel_name).all())
|
||||
except Exception:
|
||||
old_exams = []
|
||||
|
||||
for old_exam in old_exams:
|
||||
# Build a dict of field values excluding the PK
|
||||
data = model_to_dict(old_exam, exclude=["id"])
|
||||
|
||||
# Clear group membership and flags for cloned exams
|
||||
data["valid_user_users"] = [] if "valid_user_users" in data else []
|
||||
data["valid_cid_users"] = [] if "valid_cid_users" in data else []
|
||||
data["cid_user_groups"] = [] if "cid_user_groups" in data else []
|
||||
data["user_user_groups"] = [] if "user_user_groups" in data else []
|
||||
|
||||
data["active"] = False
|
||||
# some models use `archive` or `archived` - try both safely
|
||||
if "archive" in data:
|
||||
data["archive"] = False
|
||||
if "archived" in data:
|
||||
data["archived"] = False
|
||||
data["publish_results"] = False if "publish_results" in data else data.get("publish_results", False)
|
||||
|
||||
# Keep a copy of M2M fields to reapply after create
|
||||
m2m_backup = {}
|
||||
for m2m_field in ("exam_questions", "author", "markers", "valid_user_users", "valid_cid_users", "cid_user_groups", "user_user_groups"):
|
||||
if m2m_field in data:
|
||||
m2m_backup[m2m_field] = data.pop(m2m_field)
|
||||
|
||||
# Set the new examcollection foreign key to the newly created collection
|
||||
# model_to_dict returns the FK id; replace with instance for create()
|
||||
data["examcollection"] = object
|
||||
|
||||
try:
|
||||
new_exam = ExamModel.objects.create(**data)
|
||||
except Exception:
|
||||
# If creation failed for any model-specific field, skip cloning this exam
|
||||
continue
|
||||
|
||||
# Reapply M2M relationships where possible
|
||||
for field_name, ids in m2m_backup.items():
|
||||
try:
|
||||
getattr(new_exam, field_name).set(ids)
|
||||
except Exception:
|
||||
# If the field doesn't exist on this model, ignore
|
||||
pass
|
||||
|
||||
try:
|
||||
# Some exam models provide an ordering helper
|
||||
if hasattr(new_exam, "order_questions"):
|
||||
new_exam.order_questions()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return HttpResponseRedirect(object.get_absolute_url())
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user