Merge ssh://penracourses.org.uk:/home/django/rad
This commit is contained in:
+12
-4
@@ -175,12 +175,20 @@ class Long(models.Model):
|
||||
def get_image_url_array(self):
|
||||
return json.dumps(["https://www.penracourses.org.uk{}".format(i.url) for i in self.get_images()])
|
||||
|
||||
def get_unmarked_answer_count(self):
|
||||
answers = self.cid_user_answers.all()
|
||||
def get_unmarked_answer_count(self, exam_pk=None):
|
||||
if exam_pk is None:
|
||||
answers = self.cid_user_answers.all()
|
||||
else:
|
||||
answers = self.cid_user_answers.filter(exam__id=exam_pk)
|
||||
|
||||
return len([ans for ans in answers if not ans.is_marked()])
|
||||
|
||||
def get_unmarked_answers(self):
|
||||
answers = self.cid_user_answers.all()
|
||||
def get_unmarked_answers(self, exam_pk=None):
|
||||
if exam_pk is None:
|
||||
answers = self.cid_user_answers.all()
|
||||
else:
|
||||
answers = self.cid_user_answers.filter(exam__id=exam_pk)
|
||||
|
||||
return [ans for ans in answers if not ans.is_marked()]
|
||||
|
||||
def get_question_json(self, based=True):
|
||||
|
||||
@@ -128,6 +128,7 @@ class UserAnswerTable(tables.Table):
|
||||
fields = (
|
||||
"cid",
|
||||
"question",
|
||||
"score",
|
||||
#"normal",
|
||||
#"answer",
|
||||
#"answer_compare",
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
{% extends 'rapids/base.html' %}
|
||||
{% extends 'longs/base.html' %}
|
||||
|
||||
{% block content %}
|
||||
CID: {{ciduseranswer.cid}}
|
||||
@@ -8,11 +7,16 @@ CID: {{ciduseranswer.cid}}
|
||||
{{ciduseranswer.question}}
|
||||
|
||||
<h3>Answers</h3>
|
||||
{{ciduseranswer.model_observations}}<br/>
|
||||
{{ciduseranswer.model_interpretation}}<br/>
|
||||
{{ciduseranswer.model_principle_diagnosis}}<br/>
|
||||
{{ciduseranswer.model_differential_diagnosis}}<br/>
|
||||
{{ciduseranswer.model_management}}<br/>
|
||||
<h4>Observation</h4>
|
||||
<pre>{{ciduseranswer.answer_observations}}</pre><br />
|
||||
<h4>Interpretation</h4>
|
||||
<pre>{{ciduseranswer.answer_interpretation}}</pre><br />
|
||||
<h4>Principle Diagnosis</h4>
|
||||
<pre>{{ciduseranswer.answer_principle_diagnosis}}</pre><br />
|
||||
<h4>Differential Diagnosis</h4>
|
||||
<pre>{{ciduseranswer.answer_differential_diagnosis}}</pre><br />
|
||||
<h4>Managment</h4>
|
||||
<pre>{{ciduseranswer.answer_management}}</pre><br />
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
<a href="{% url 'longs:exam_question_detail' exam.id forloop.counter0 %}"
|
||||
title="View the question">View</a> / <a href="{% url 'longs:long_update' question.id %}"
|
||||
title="Edit the question">Edit</a>
|
||||
<span class="id">[id: {{question.pk}}]</span>
|
||||
</div>
|
||||
</span>
|
||||
<span class="flex-col-3">
|
||||
|
||||
@@ -44,14 +44,14 @@
|
||||
<tr>
|
||||
<th>Candidate</th>
|
||||
{% for cid in cids %}
|
||||
<th>{{cid}}</th>
|
||||
<th><a href="{% url 'longs:exam_scores_cid_user' exam.pk cid %}">{{cid}}</a></th>
|
||||
{% endfor %}
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
{% for question in questions %}
|
||||
<tr>
|
||||
<td>Question {{forloop.counter}}</td>
|
||||
<td><a href="{% url 'longs:mark' pk=exam.pk sk=forloop.counter0 %}">Question {{forloop.counter}}</a></td>
|
||||
{% for ans, score in by_question|get_item:question %}
|
||||
<td class="user-answer-score-{{score}}" title="answer score: {{score}}">{{score}}</td>
|
||||
{% endfor %}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
<div class="date">
|
||||
{{ question.created_date|date:"d/m/Y" }}
|
||||
</div>
|
||||
<div class="id">
|
||||
ID: {{ question.id }}
|
||||
</div>
|
||||
<p class="pre-whitespace"><b>Description:</b> {{ question.description }}</p>
|
||||
|
||||
<p class="pre-whitespace"><b>History:</b> {{ question.history }}</p>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{% extends 'longs/exams.html' %}
|
||||
|
||||
{% block content %}
|
||||
<a href="{% url 'longs:exam_question_detail' exam.id question_details.current %}" title="View the Question">View</a>
|
||||
<a href="{% url 'longs:exam_question_detail' exam.id question_details.current|add:'-1' %}"
|
||||
title="View the Question">View</a>
|
||||
<a href="{% url 'longs:long_update' question.id %}" title="Edit the Question">Edit</a> <a
|
||||
href="{% url 'admin:longs_long_change' question.id %}" title="Edit the Question using the admin interface">Admin
|
||||
Edit</a>
|
||||
|
||||
@@ -13,9 +13,19 @@
|
||||
title="View question answers">{{question_details.current}}</a> of {{question_details.total}}</h2>
|
||||
|
||||
{% if not next_unmarked_id and not unmarked %}
|
||||
<div class="alert alert-info" role="alert">Success! Marking question complete. <a
|
||||
href="{% url 'longs:mark_overview' pk=exam.pk %}">Return to marking
|
||||
overview</a></div>
|
||||
<div class="alert alert-info sticky-alert" role="alert">Success! Marking question complete. <br />Return to <a
|
||||
href="{% url 'longs:mark' exam.id question_details.current|add:'-1' %}">question
|
||||
overview</a>, <a href="{% url 'longs:mark_overview' pk=exam.pk %}">marking
|
||||
overview</a><br />
|
||||
{% if previous_cid %}
|
||||
<a href="{% url 'longs:mark_answer' pk=exam.pk sk=question_details.current|add:'-1' cid=previous_cid %}">Previous
|
||||
candidate</a>
|
||||
{% endif %}
|
||||
{% if next_cid %}
|
||||
<a href="{% url 'longs:mark_answer' pk=exam.pk sk=question_details.current|add:'-1' cid=next_cid %}">Next
|
||||
candidate</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<span>Marking CID: {{answer.cid}} ({{unmarked|length}} answer(s) left to mark)</span>
|
||||
@@ -89,4 +99,11 @@
|
||||
{% endif %}
|
||||
</form>
|
||||
</div>
|
||||
{% if previous_cid %}
|
||||
<a href="{% url 'longs:mark_answer' pk=exam.pk sk=question_details.current|add:'-1' cid=previous_cid %}">Previous
|
||||
candidate</a>
|
||||
{% endif %}
|
||||
{% if next_cid %}
|
||||
<a href="{% url 'longs:mark_answer' pk=exam.pk sk=question_details.current|add:'-1' cid=next_cid %}">Next candidate</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -6,16 +6,16 @@
|
||||
You can start marking from a particular question by clicking on it below.
|
||||
|
||||
<div>
|
||||
<button class="show-all-button">Show all</button><button class="show-unmarked-button">Show unmarked</button>
|
||||
<button class="show-all-button">Show all</button><button class="show-unmarked-button">Show unmarked</button>
|
||||
</div>
|
||||
<div id="stark-marking-button"><a href="{% url 'longs:mark' pk=exam.pk sk=0 %}"><button>Click here to start marking</button></a></div>
|
||||
<div id="stark-marking-button"><a href="{% url 'longs:mark' pk=exam.pk sk=0 %}"><button>Click here to start
|
||||
marking</button></a></div>
|
||||
|
||||
<ul id="question-mark-list">
|
||||
{% for question in questions.all %}
|
||||
<li data-markcount={{question.get_unmarked_answer_count}}
|
||||
{% if question.get_unmarked_answer_count %}class="unmarked" {% endif %}
|
||||
><a href="{% url 'longs:mark' pk=exam.pk sk=forloop.counter0 %}">Question {{forloop.counter }}:
|
||||
{{ question }}</a><br /> Answers to mark: {{question.get_unmarked_answer_count}}</li>
|
||||
{% for question, unmarked_count in question_unmarked_map %}
|
||||
<li data-markcount={{unmarked_count}} {% if unmarked_count %}class="unmarked" {% endif %}><a
|
||||
href="{% url 'longs:mark' pk=exam.pk sk=forloop.counter0 %}">Question {{forloop.counter }}:
|
||||
{{ question }}</a><br /> Answers to mark: {{unmarked_count}}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ urlpatterns = [
|
||||
# path("all_questions/", views.all_questions, name="all_questions"),
|
||||
path("question/<int:pk>/scrap", views.long_scrap, name="long_scrap"),
|
||||
path("question/<int:pk>/delete", views.LongDelete.as_view(), name="long_delete"),
|
||||
path("exam/<int:pk>/<int:sk>/<int:tk>/mark", views.mark_answer, name="mark_answer"),
|
||||
path("exam/<int:pk>/<int:sk>/<int:cid>/mark", views.mark_answer, name="mark_answer"),
|
||||
path("exam/<int:pk>/<int:sk>/mark", views.mark, name="mark"),
|
||||
path("exam/<int:pk>/mark", views.LongExamViews.mark_overview, name="mark_overview"),
|
||||
# path("exam/<int:pk>/<int:sk>/", views.exam_take, name="exam_take"),
|
||||
|
||||
+33
-6
@@ -468,6 +468,10 @@ class LongUpdate(RevisionMixin, LoginRequiredMixin, AuthorOrCheckerRequiredMixin
|
||||
return context
|
||||
|
||||
def form_valid(self, form):
|
||||
# save exam orders (there must be a better way to do this)
|
||||
exam_orders = {}
|
||||
for exam in self.object.exams.all():
|
||||
exam_orders[exam] = list(exam.exam_questions.all())
|
||||
|
||||
self.object = form.save(commit=False)
|
||||
self.object.save()
|
||||
@@ -486,6 +490,14 @@ class LongUpdate(RevisionMixin, LoginRequiredMixin, AuthorOrCheckerRequiredMixin
|
||||
response = super().form_valid(form)
|
||||
series_formset.instance = self.object
|
||||
series_formset.save()
|
||||
|
||||
# restore exam orders
|
||||
for exam in self.object.exams.all():
|
||||
if exam in exam_orders and self.object in exam_orders[exam]:
|
||||
print(exam_orders[exam])
|
||||
exam.exam_questions.set(exam_orders[exam])
|
||||
exam.save()
|
||||
|
||||
return response
|
||||
else:
|
||||
return super().form_invalid(form)
|
||||
@@ -639,7 +651,7 @@ def loadJsonAnswer(answer):
|
||||
@login_required
|
||||
@user_is_long_marker
|
||||
@reversion.create_revision()
|
||||
def mark_answer(request, pk, sk, tk):
|
||||
def mark_answer(request, pk, sk, cid):
|
||||
exam = get_object_or_404(Exam, pk=pk)
|
||||
|
||||
questions = exam.exam_questions.all()
|
||||
@@ -657,14 +669,27 @@ def mark_answer(request, pk, sk, tk):
|
||||
raise Http404("Exam question does not exist")
|
||||
|
||||
try:
|
||||
answer = question.cid_user_answers.get(cid=tk, exam__id=pk)
|
||||
answer = question.cid_user_answers.get(cid=cid, exam__id=pk)
|
||||
except ObjectDoesNotExist:
|
||||
raise Http404("User answer does not exist")
|
||||
|
||||
cid_list = list(question.cid_user_answers.filter(exam__id=pk).values_list("cid", flat=True))
|
||||
|
||||
previous_cid = False
|
||||
next_cid = False
|
||||
|
||||
if cid_list[0] == cid:
|
||||
next_cid = cid_list[1]
|
||||
elif cid_list[-1] == cid:
|
||||
previous_cid = cid_list[-2]
|
||||
else:
|
||||
next_cid = cid_list[cid_list.index(cid)+1]
|
||||
previous_cid = cid_list[cid_list.index(cid)-1]
|
||||
|
||||
try:
|
||||
unmarked = question.get_unmarked_answers()
|
||||
next_unmarked_id = unmarked[0].cid
|
||||
if next_unmarked_id == tk:
|
||||
if next_unmarked_id == cid:
|
||||
next_unmarked_id = unmarked[1].cid
|
||||
except IndexError:
|
||||
next_unmarked_id = False
|
||||
@@ -677,16 +702,16 @@ def mark_answer(request, pk, sk, tk):
|
||||
# If skip button is pressed skip the question without marking
|
||||
# Skip is problematic if we skip to the next unmarked answer
|
||||
#if "skip" in request.POST:
|
||||
# return redirect("longs:mark_answer", pk=pk, sk=sk, tk=next_unmarked_id)
|
||||
# return redirect("longs:mark_answer", pk=pk, sk=sk, cid=next_unmarked_id)
|
||||
|
||||
# Extract score from form and save it to the object
|
||||
answer.score = form.cleaned_data["score"]
|
||||
answer.save()
|
||||
|
||||
if "next" in request.POST:
|
||||
return redirect("longs:mark_answer", pk=pk, sk=sk, tk=next_unmarked_id)
|
||||
return redirect("longs:mark_answer", pk=pk, sk=sk, cid=next_unmarked_id)
|
||||
if "save" in request.POST:
|
||||
return redirect("longs:mark_answer", pk=pk, sk=sk, tk=tk)
|
||||
return redirect("longs:mark_answer", pk=pk, sk=sk, cid=cid)
|
||||
#elif "previous" in request.POST:
|
||||
# return redirect("longs:mark", pk=pk, sk=n - 1)
|
||||
|
||||
@@ -705,6 +730,8 @@ def mark_answer(request, pk, sk, tk):
|
||||
"question_details": question_details,
|
||||
"next_unmarked_id": next_unmarked_id,
|
||||
"unmarked": unmarked,
|
||||
"previous_cid": previous_cid,
|
||||
"next_cid": next_cid,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user