Add user answer viewing and compaction
This commit is contained in:
@@ -3897,6 +3897,7 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
"total_score": total_score,
|
||||
"max_score": max_score,
|
||||
"answers_and_marks": answers_and_marks,
|
||||
"user_answers_map": user_answers_map,
|
||||
"view_all_results": view_all_results,
|
||||
"supervisor": supervisor,
|
||||
#"cid_user_exam": cid_user_exam,
|
||||
@@ -5238,6 +5239,135 @@ def import_exam_answers(request):
|
||||
del request.session["pending_import_data"]
|
||||
return render(request, "generic/import_exam_answers.html")
|
||||
|
||||
|
||||
def compact_history_for_object(obj):
|
||||
"""
|
||||
Helper function to delete all historical revisions for a registered object,
|
||||
leaving only the most recent version.
|
||||
"""
|
||||
from reversion.models import Version
|
||||
versions = Version.objects.get_for_object(obj).order_by("-revision__date_created")
|
||||
count = versions.count()
|
||||
if count > 1:
|
||||
# Keep the latest version, delete older versions and their revisions
|
||||
recent_version = versions[0]
|
||||
old_versions = list(versions[1:])
|
||||
for v in old_versions:
|
||||
revision = v.revision
|
||||
v.delete()
|
||||
if not revision.version_set.exists():
|
||||
revision.delete()
|
||||
return count - 1
|
||||
return 0
|
||||
|
||||
|
||||
@login_required
|
||||
def view_answer_history(request, app_name, model_name, pk):
|
||||
"""
|
||||
View to display the revision history for a user/candidate answer,
|
||||
and compact history (individual and bulk).
|
||||
"""
|
||||
from django.contrib import messages
|
||||
from django.apps import apps
|
||||
from reversion.models import Version
|
||||
|
||||
try:
|
||||
Model = apps.get_model(app_name, model_name)
|
||||
except LookupError:
|
||||
raise Http404("Model not found")
|
||||
|
||||
answer = get_object_or_404(Model, pk=pk)
|
||||
|
||||
# Check permissions
|
||||
can_view = (
|
||||
request.user.is_staff
|
||||
or request.user.is_superuser
|
||||
or request.user.groups.filter(name__in=[
|
||||
"cid_user_manager", "anatomy_checker", "rapid_checker", "long_checker"
|
||||
]).exists()
|
||||
)
|
||||
|
||||
exam = getattr(answer, "exam", None)
|
||||
collection = None
|
||||
if hasattr(answer, "question") and hasattr(answer.question, "collection"):
|
||||
collection = answer.question.collection
|
||||
|
||||
if not can_view:
|
||||
if exam and hasattr(exam, "author") and request.user in exam.author.all():
|
||||
can_view = True
|
||||
if collection and hasattr(collection, "author") and request.user in collection.author.all():
|
||||
can_view = True
|
||||
|
||||
if not can_view:
|
||||
raise PermissionDenied("You do not have permission to view this answer's history")
|
||||
|
||||
if request.method == "POST":
|
||||
action = request.POST.get("action")
|
||||
if action == "compact_single":
|
||||
compacted = compact_history_for_object(answer)
|
||||
messages.success(request, f"Compacted single answer history. Removed {compacted} old revisions.")
|
||||
return HttpResponseRedirect(request.path)
|
||||
|
||||
elif action == "compact_bulk":
|
||||
compacted_total = 0
|
||||
if exam:
|
||||
answers_qs = Model.objects.filter(exam=exam)
|
||||
for ans in answers_qs:
|
||||
compacted_total += compact_history_for_object(ans)
|
||||
messages.success(request, f"Bulk compacted history for all answers in Exam '{exam}'. Removed {compacted_total} old revisions.")
|
||||
elif collection:
|
||||
from atlas.models import CidReportAnswer, UserReportAnswer
|
||||
cids_qs = CidReportAnswer.objects.filter(question__collection=collection)
|
||||
users_qs = UserReportAnswer.objects.filter(question__collection=collection)
|
||||
for ans in cids_qs:
|
||||
compacted_total += compact_history_for_object(ans)
|
||||
for ans in users_qs:
|
||||
compacted_total += compact_history_for_object(ans)
|
||||
messages.success(request, f"Bulk compacted history for all answers in Case Collection '{collection}'. Removed {compacted_total} old revisions.")
|
||||
return HttpResponseRedirect(request.path)
|
||||
|
||||
# GET request
|
||||
versions = Version.objects.get_for_object(answer).select_related("revision__user").order_by("-revision__date_created")
|
||||
|
||||
history_data = []
|
||||
for v in versions:
|
||||
fields = v.field_dict
|
||||
|
||||
# Format answer contents nicely based on model/app
|
||||
ans_text = fields.get("answer", "")
|
||||
if not ans_text:
|
||||
if model_name.lower() == "useranswer" and app_name.lower() == "longs":
|
||||
ans_text = (
|
||||
f"Observations: {fields.get('answer_observations', '')}\n"
|
||||
f"Interpretation: {fields.get('answer_interpretation', '')}\n"
|
||||
f"Diagnosis: {fields.get('answer_principle_diagnosis', '')}\n"
|
||||
f"Differential: {fields.get('answer_differential_diagnosis', '')}\n"
|
||||
f"Management: {fields.get('answer_management', '')}"
|
||||
)
|
||||
elif model_name.lower() == "useranswer" and app_name.lower() == "physics":
|
||||
ans_text = f"A: {fields.get('a')}, B: {fields.get('b')}, C: {fields.get('c')}, D: {fields.get('d')}, E: {fields.get('e')}"
|
||||
|
||||
history_data.append({
|
||||
"revision_id": v.revision_id,
|
||||
"date": v.revision.date_created,
|
||||
"user": v.revision.user,
|
||||
"answer_text": ans_text,
|
||||
"score": fields.get("score", ""),
|
||||
"comment": v.revision.comment,
|
||||
})
|
||||
|
||||
context = {
|
||||
"answer": answer,
|
||||
"history": history_data,
|
||||
"exam": exam,
|
||||
"collection": collection,
|
||||
"app_name": app_name,
|
||||
"model_name": model_name,
|
||||
}
|
||||
|
||||
return render(request, "generic/answer_history.html", context)
|
||||
|
||||
|
||||
@user_is_cid_user_manager
|
||||
def user_group_add_by_email_user(request, group_id):
|
||||
if request.htmx:
|
||||
|
||||
Reference in New Issue
Block a user