Merge branch 'master' of ssh://web.xkjq.uk:30001/ross/rad

This commit is contained in:
Ross
2021-01-07 15:29:27 +00:00
9 changed files with 71 additions and 14 deletions
@@ -0,0 +1,25 @@
# Generated by Django 3.1.2 on 2021-01-04 13:10
import anatomy.models
import django.core.files.storage
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('anatomy', '0015_auto_20201228_2235'),
]
operations = [
migrations.AlterField(
model_name='anatomyquestion',
name='image',
field=models.ImageField(storage=django.core.files.storage.FileSystemStorage(base_url='http://penracourses.org.uk//media/anatomy/', location='/home/ross/sites/rad/media//anatomy/'), upload_to=anatomy.models.image_directory_path),
),
migrations.AlterField(
model_name='useranswer',
name='cid',
field=models.BigIntegerField(blank=True, null=True),
),
]
@@ -0,0 +1,23 @@
# Generated by Django 3.1.2 on 2021-01-04 13:55
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('anatomy', '0016_auto_20210104_1310'),
]
operations = [
migrations.AlterField(
model_name='ciduseranswer',
name='cid',
field=models.BigIntegerField(blank=True, help_text='Candidate ID (limitied by BigIntegerField size)', null=True),
),
migrations.AlterField(
model_name='useranswer',
name='cid',
field=models.BigIntegerField(blank=True, help_text='Candidate ID (limitied by BigIntegerField size)', null=True),
),
]
+2 -2
View File
@@ -297,7 +297,7 @@ class UserAnswer(models.Model):
settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL
) )
cid = models.IntegerField(blank=True, null=True) cid = models.BigIntegerField(blank=True, null=True, help_text="Candidate ID (limitied by BigIntegerField size)")
# Each user answer is associated with a particular exam # Each user answer is associated with a particular exam
exam = models.ForeignKey( exam = models.ForeignKey(
@@ -331,7 +331,7 @@ class CidUserAnswer(models.Model):
) )
answer = models.TextField(max_length=500, blank=True) answer = models.TextField(max_length=500, blank=True)
cid = models.IntegerField(blank=True, null=True) cid = models.BigIntegerField(blank=True, null=True, help_text="Candidate ID (limitied by BigIntegerField size)")
# Each user answer is associated with a particular exam # Each user answer is associated with a particular exam
exam = models.ForeignKey( exam = models.ForeignKey(
+10 -6
View File
@@ -26,7 +26,8 @@ a, a:link {
} }
.answer-list .correct { .answer-list .correct {
color: green; /* color: green; */
color: lightblue;
} }
.answer-list .correct::after{ .answer-list .correct::after{
@@ -53,7 +54,7 @@ a, a:link {
} }
.answer-list .not-marked { .answer-list .not-marked {
color: lightblue; color: white;
} }
.key { .key {
@@ -65,7 +66,8 @@ a, a:link {
} }
.answered { .answered {
color: green; /* color: green; */
color: lightblue;
} }
.unanswered { .unanswered {
@@ -319,11 +321,12 @@ img.uploading:hover {
} }
.user-answer-score-1 { .user-answer-score-1 {
color: greenyellow; color: yellow;
} }
.user-answer-score-2 { .user-answer-score-2 {
color: green; /* color: green; */
color: lightblue;
} }
td.user-answer-score-0::after { td.user-answer-score-0::after {
@@ -383,7 +386,8 @@ td.user-answer-score-2::after {
} }
.answer-1 { .answer-1 {
color: green; /* color: green; */
color: lightblue;
} }
.answer-0 { .answer-0 {
+1 -1
View File
@@ -31,7 +31,7 @@ $(document).ready(function () {
if($(".post-form").length > 0) { if($(".post-form").length > 0) {
$(".post-form").get(0).addEventListener("submit", function (e) { $(".post-form").get(0).addEventListener("submit", function (e) {
if($(".not-marked").length > 0) { if($(".not-marked").length > 0 && e.submitter.name != "skip") {
e.preventDefault(); // before the code e.preventDefault(); // before the code
alert("Ensure all answers are marked first"); alert("Ensure all answers are marked first");
} }
+1 -1
View File
@@ -26,7 +26,7 @@
<br /> <br />
{{ question.question_type }}: {{ question.GetPrimaryAnswer }} {{ question.question_type }}: {{ question.GetPrimaryAnswer }}
<br /> <br />
Modality: {{ question.modality }}, <a href="{% url 'anatomy:exam_question_detail' pk=exam.pk sk=forloop.counter0 %}">View</a> Modality: {{ question.modality }}, <a href="{% url 'anatomy:exam_question_detail' pk=exam.pk sk=forloop.counter0 %}">View</a>, <a href="{% url 'anatomy:mark' pk=exam.pk sk=forloop.counter0 %}">Mark</a>
</li> </li>
{% endfor %} {% endfor %}
</ol> </ol>
+1
View File
@@ -38,6 +38,7 @@
{% if question_details.current >= question_details.total %} {% if question_details.current >= question_details.total %}
{% else %} {% else %}
<button type="submit" name="next" class="save btn btn-default">Next</button> <button type="submit" name="next" class="save btn btn-default">Next</button>
<button type="submit" name="skip" class="save btn btn-default">Skip</button>
{% endif %} {% endif %}
</div> </div>
<span class=hide> <span class=hide>
+1 -1
View File
@@ -3,7 +3,7 @@
{% block content %} {% block content %}
<div class="anatomy"> <div class="anatomy">
<h2>Marking exam: {{ exam.name }}</h2> <h2>Marking exam: {{ exam.name }}</h2>
Question order may be different on the test system (as json order is not guaranteed to be maintained) You can start marking from a particular question by clicking on it below.
<div> <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>
+7 -3
View File
@@ -281,12 +281,12 @@ def loadJsonAnswer(answer):
if (not isinstance(answer["cid"], int)) or ( if (not isinstance(answer["cid"], int)) or (
not isinstance(answer["eid"], int) or (not isinstance(answer["ans"], str)) not isinstance(answer["eid"], int) or (not isinstance(answer["ans"], str))
): ):
return JsonResponse({"success": False}) return JsonResponse({"success": False, "error": "cid or eid or answers not defined"})
# The model should catch invalid data but this should be less intensive # The model should catch invalid data but this should be less intensive
max_int = 10000000 max_int = 999999999999999999999
if answer["cid"] > max_int or answer["eid"] > max_int: if answer["cid"] > max_int or answer["eid"] > max_int:
return JsonResponse({"success": False}) return JsonResponse({"success": False, "error": "invalid cid"})
exam = get_object_or_404(Exam, pk=answer["eid"]) exam = get_object_or_404(Exam, pk=answer["eid"])
@@ -420,6 +420,10 @@ def mark(request, pk, sk):
# TODO: convert to JSON request # TODO: convert to JSON request
# ******************************* # *******************************
if form.is_valid(): if form.is_valid():
# If skip button is pressed skip the question without marking
if "skip" in request.POST:
return redirect("anatomy:mark", pk=pk, sk=n + 1)
cd = form.cleaned_data cd = form.cleaned_data
# correct = cd.get("correct") # correct = cd.get("correct")
# half_correct = cd.get("half_correct") # half_correct = cd.get("half_correct")