add markers to exams (move away from group based to content based permissions)
This commit is contained in:
+6
-2
@@ -8,7 +8,7 @@ from django.forms import (
|
||||
CharField,
|
||||
)
|
||||
from django.forms import inlineformset_factory
|
||||
from generic.forms import ExamAuthorFormMixin, ExamFormMixin
|
||||
from generic.forms import ExamAuthorFormMixin, ExamFormMixin, ExamMarkerFormMixin
|
||||
|
||||
from longs.models import (
|
||||
# Examination,
|
||||
@@ -313,4 +313,8 @@ class ExamForm(ExamFormMixin, ModelForm):
|
||||
class ExamAuthorForm(ExamAuthorFormMixin):
|
||||
class Meta(ExamAuthorFormMixin.Meta):
|
||||
model = Exam
|
||||
#fields = ExamAuthorFormMixin.Meta.fields.append("double_mark")
|
||||
#fields = ExamAuthorFormMixin.Meta.fields.append("double_mark")
|
||||
|
||||
class ExamMarkerForm(ExamMarkerFormMixin):
|
||||
class Meta(ExamMarkerFormMixin.Meta):
|
||||
model = Exam
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# Generated by Django 5.0.2 on 2024-08-05 09:43
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('longs', '0025_remove_answermarks_candidate_feedback_and_more'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='exam',
|
||||
name='markers',
|
||||
field=models.ManyToManyField(blank=True, help_text='Authorised markers for the exam', related_name='long_exam_markers', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
@@ -445,6 +445,13 @@ class Exam(ExamBase):
|
||||
help_text="Author of exam",
|
||||
related_name="long_exam_author",
|
||||
)
|
||||
|
||||
markers = models.ManyToManyField(
|
||||
settings.AUTH_USER_MODEL,
|
||||
blank=True,
|
||||
help_text="Authorised markers for the exam",
|
||||
related_name="long_exam_markers",
|
||||
)
|
||||
|
||||
double_mark = models.BooleanField(
|
||||
default=True, help_text="Defines if an exam is expected to be double marked"
|
||||
|
||||
@@ -176,7 +176,6 @@ def test_exams(db, client):
|
||||
|
||||
active_exams_cid = client.get(active_exams_url)
|
||||
|
||||
print(cid_user)
|
||||
assert active_exams_cid.status_code == 200
|
||||
assert len(json.loads(active_exams_cid.content)["exams"]) == 1
|
||||
|
||||
@@ -202,7 +201,6 @@ def test_exams(db, client):
|
||||
assert exam_metadata["name"] == "Cid Exam"
|
||||
assert exam_metadata["exam_active"] == True
|
||||
assert exam_metadata["exam_mode"] == True
|
||||
print(f"{exam_metadata=}")
|
||||
|
||||
res = client.get(exam_metadata["url"])
|
||||
assert res.status_code == 200
|
||||
@@ -224,7 +222,6 @@ def test_exams(db, client):
|
||||
)
|
||||
|
||||
for q in exam_json["question_requests"]:
|
||||
print("check question:", q)
|
||||
# check redirects to the json file work
|
||||
# TODO: sort out testing of the saved JSON files
|
||||
try:
|
||||
@@ -258,8 +255,6 @@ def test_exams(db, client):
|
||||
|
||||
assert question_json_res.redirect_chain[1][0].endswith(f"{q}.json")
|
||||
|
||||
print(cid_user, testing_cid_user)
|
||||
|
||||
if testing_cid_user:
|
||||
question_json_unbased_res = client.get(
|
||||
reverse(
|
||||
@@ -281,7 +276,6 @@ def test_exams(db, client):
|
||||
"sk": q,
|
||||
},
|
||||
)
|
||||
print(test)
|
||||
question_json_unbased_res = client.get(
|
||||
|
||||
reverse(
|
||||
@@ -516,8 +510,6 @@ def test_exams(db, client):
|
||||
|
||||
assert len(answer_lis) == len(valid_answers_by_question)
|
||||
|
||||
pprint(valid_answers_by_question)
|
||||
print(cid_user)
|
||||
|
||||
for n in range(
|
||||
len(valid_answers_by_question)
|
||||
@@ -526,7 +518,6 @@ def test_exams(db, client):
|
||||
#n = str(n + 1) # questions are not zero indexed (lists are)
|
||||
|
||||
for qidn, section_title in sections:
|
||||
print(n, qidn)
|
||||
answer = valid_answers_by_question[n][qidn]
|
||||
|
||||
li = lis.find("li", attrs={"data-qidn": qidn})
|
||||
@@ -558,6 +549,19 @@ def test_exams(db, client):
|
||||
assert "Not answered" in str(answer_lis[-1])
|
||||
assert str(answer_lis[-1]).count("Not answered") == 5
|
||||
|
||||
|
||||
## Load the mark overview page
|
||||
#mark_overview_res = client.get(reverse(
|
||||
# f"{exam.app_name}:mark_overview",
|
||||
# kwargs={"pk": exam.pk},
|
||||
# ))
|
||||
#print(mark_overview_res.content)
|
||||
#mark_overview_soup = BeautifulSoup(mark_overview_res.content, "html.parser")
|
||||
|
||||
#to_mark = mark_overview_soup.find("ul", {"id": "question-mark-list"}).find_all("li")
|
||||
#assert len(to_mark) == 5
|
||||
|
||||
|
||||
# Publish the results!
|
||||
exam.publish_results = True
|
||||
exam.save()
|
||||
@@ -594,8 +598,6 @@ def test_exams(db, client):
|
||||
|
||||
assert answer["ans"] in str(li) # Check that the saved answer is shown
|
||||
|
||||
print(cid_exam_scores_soup.find("div", {"class": "score-overview"}))
|
||||
|
||||
# For long cases an unmarked answers is given a score of 4
|
||||
# Each user needs marking individually
|
||||
assert (
|
||||
@@ -609,10 +611,8 @@ def test_exams(db, client):
|
||||
# For longs this needs to be done for each user
|
||||
question: Question
|
||||
for question in exam.exam_questions.all():
|
||||
print(question)
|
||||
|
||||
answers = question.get_unmarked_user_answers()
|
||||
print(answers)
|
||||
for answer in answers:
|
||||
answer.score = UserAnswer.ScoreOptions.EIGHT
|
||||
answer.save()
|
||||
|
||||
@@ -82,6 +82,7 @@ urlpatterns = [
|
||||
views.mark,
|
||||
name="mark",
|
||||
),
|
||||
path("exam/<int:pk>/markers", views.ExamMarkersUpdate.as_view(), name="exam_markers"),
|
||||
path("exam/<int:pk>/authors", views.ExamAuthorUpdate.as_view(), name="exam_authors"),
|
||||
path(
|
||||
"exam/<int:pk>/question_json_refresh",
|
||||
|
||||
@@ -26,6 +26,7 @@ from django.http import HttpResponseRedirect, HttpResponse
|
||||
|
||||
from .forms import (
|
||||
ExamAuthorForm,
|
||||
ExamMarkerForm,
|
||||
LongForm,
|
||||
LongSeriesForm,
|
||||
LongSeriesImageFormSet,
|
||||
@@ -977,6 +978,14 @@ class ExamAuthorUpdate(
|
||||
form_class = ExamAuthorForm
|
||||
template_name = "author_form.html"
|
||||
|
||||
class ExamMarkersUpdate(
|
||||
RevisionMixin, CheckCanEditMixin, LoginRequiredMixin, AuthorRequiredMixin, UpdateView
|
||||
):
|
||||
model = Exam
|
||||
form_class = ExamMarkerForm
|
||||
|
||||
template_name = "markers_form.html"
|
||||
|
||||
|
||||
# class ExamViewSet(RevisionMixin, viewsets.ModelViewSet):
|
||||
# queryset = Exam.objects.all().order_by("name")
|
||||
|
||||
Reference in New Issue
Block a user