.
This commit is contained in:
+241
-241
@@ -1,241 +1,241 @@
|
||||
from django.forms import (
|
||||
Form,
|
||||
ModelForm,
|
||||
ModelMultipleChoiceField,
|
||||
ModelChoiceField,
|
||||
ChoiceField,
|
||||
CharField,
|
||||
)
|
||||
from django.forms import inlineformset_factory
|
||||
|
||||
from rapids.models import (
|
||||
Abnormality,
|
||||
Examination,
|
||||
Rapid,
|
||||
RapidCreationDefault,
|
||||
RapidImage,
|
||||
Region,
|
||||
Answer,
|
||||
CidUserAnswer,
|
||||
Exam,
|
||||
)
|
||||
|
||||
from django.contrib.admin.widgets import FilteredSelectMultiple
|
||||
from django.forms.widgets import RadioSelect, TextInput, Textarea
|
||||
|
||||
|
||||
class RapidAnswerForm(ModelForm):
|
||||
class Meta:
|
||||
model = CidUserAnswer
|
||||
fields = ("answer",)
|
||||
|
||||
|
||||
class MarkRapidQuestionForm(Form):
|
||||
# correct = forms.CharField(required=False)
|
||||
# half_correct = forms.CharField(required=False)
|
||||
# incorrect = forms.CharField(required=False)
|
||||
marked_answers = CharField(required=False)
|
||||
|
||||
|
||||
class ExaminationForm(ModelForm):
|
||||
class Meta:
|
||||
model = Examination
|
||||
fields = ["examination"]
|
||||
|
||||
|
||||
class RegionForm(ModelForm):
|
||||
class Meta:
|
||||
model = Region
|
||||
fields = ["name"]
|
||||
|
||||
|
||||
class AbnormalityForm(ModelForm):
|
||||
class Meta:
|
||||
model = Abnormality
|
||||
fields = ["name"]
|
||||
|
||||
|
||||
class RapidCreationDefaultForm(ModelForm):
|
||||
class Meta:
|
||||
model = RapidCreationDefault
|
||||
# fields = ["site"]
|
||||
exclude = ["author"]
|
||||
|
||||
|
||||
class RapidForm(ModelForm):
|
||||
|
||||
# exams = ModelMultipleChoiceField(required=False, queryset=Exam.objects.all(),widget=FilteredSelectMultiple(verbose_name="Exams", is_stacked=False))
|
||||
class Media:
|
||||
# Django also includes a few javascript files necessary
|
||||
# for the operation of this form element. You need to
|
||||
# include <script src="/admin/jsi18n"></script>
|
||||
# in the template.
|
||||
css = {
|
||||
"all": ["css/widgets.css"],
|
||||
}
|
||||
# Adding this javascript is crucial
|
||||
js = ["jsi18n.js", "tesseract.min.js"]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.user = kwargs.pop(
|
||||
"user"
|
||||
) # To get request.user. Do not use kwargs.pop('user', None) due to potential security hole
|
||||
if kwargs.get("instance"):
|
||||
# We get the 'initial' keyword argument or initialize it
|
||||
# as a dict if it didn't exist.
|
||||
initial = kwargs.setdefault("initial", {})
|
||||
# The widget for a ModelMultipleChoiceField expects
|
||||
# a list of primary key for the selected data.
|
||||
initial["exams"] = [t.pk for t in kwargs["instance"].exams.all()]
|
||||
|
||||
ModelForm.__init__(self, *args, **kwargs)
|
||||
super(RapidForm, self).__init__(*args, **kwargs)
|
||||
# self.fields['question'].widget.attrs = {'class': 'question-form', 'rows': 10, 'cols': 100}
|
||||
# self.fields['feedback'].widget.attrs = {'class': 'feedback-form', 'rows': 10, 'cols': 100}
|
||||
|
||||
self.fields["abnormality"] = ModelMultipleChoiceField(
|
||||
required=False,
|
||||
queryset=Abnormality.objects.all(),
|
||||
widget=FilteredSelectMultiple(verbose_name="Abnormality", is_stacked=False),
|
||||
)
|
||||
|
||||
self.fields["region"] = ModelMultipleChoiceField(
|
||||
required=False,
|
||||
queryset=Region.objects.all(),
|
||||
widget=FilteredSelectMultiple(verbose_name="Region", is_stacked=False),
|
||||
)
|
||||
|
||||
self.fields["examination"] = ModelMultipleChoiceField(
|
||||
queryset=Examination.objects.all(),
|
||||
widget=FilteredSelectMultiple(verbose_name="Examination", is_stacked=False),
|
||||
)
|
||||
|
||||
self.fields["laterality"] = ChoiceField(
|
||||
choices=Rapid.LATERALITY_CHOICES, required=False, widget=RadioSelect()
|
||||
)
|
||||
|
||||
if self.user.groups.filter(name="rapid_checker").exists():
|
||||
exam_queryset = Exam.objects.all()
|
||||
else:
|
||||
exam_queryset = Exam.objects.filter(
|
||||
author__id=self.user.id
|
||||
) | Exam.objects.filter(open_access=True)
|
||||
|
||||
self.fields["exams"] = ModelMultipleChoiceField(
|
||||
required=False,
|
||||
queryset=exam_queryset,
|
||||
widget=FilteredSelectMultiple(verbose_name="Exams", is_stacked=False),
|
||||
)
|
||||
|
||||
def save(self, commit=True):
|
||||
instance = ModelForm.save(self, False)
|
||||
instance.save()
|
||||
|
||||
old_exams = instance.exams.all()
|
||||
|
||||
new_exams = self.cleaned_data["exams"]
|
||||
|
||||
for exam in old_exams:
|
||||
if exam not in new_exams:
|
||||
exam.exam_questions.remove(instance)
|
||||
|
||||
for exam in new_exams:
|
||||
exam.exam_questions.add(instance)
|
||||
#exam.save()
|
||||
|
||||
# # Prepare a 'save_m2m' method for the form,
|
||||
# old_save_m2m = self.save_m2m
|
||||
#
|
||||
# def save_m2m():
|
||||
# old_save_m2m()
|
||||
# # This is where we actually link the pizza with toppings
|
||||
# instance.exams.clear()
|
||||
# for exam in self.cleaned_data["exams"]:
|
||||
# instance.exams.add(exam)
|
||||
#
|
||||
# self.save_m2m = save_m2m
|
||||
#
|
||||
# # Do we need to save all changes now?
|
||||
# # if commit:
|
||||
# instance.save()
|
||||
self.save_m2m()
|
||||
|
||||
return instance
|
||||
|
||||
class Meta:
|
||||
model = Rapid
|
||||
# fields = ['due_back']
|
||||
# fields = '__all__'
|
||||
fields = [
|
||||
"normal",
|
||||
"abnormality",
|
||||
"region",
|
||||
"laterality",
|
||||
"examination",
|
||||
# "site",
|
||||
"feedback",
|
||||
"open_access",
|
||||
]
|
||||
# fields = ['question', 'feedback', 'subspecialty', 'references']
|
||||
widgets = {
|
||||
# "normal": RadioSelect(
|
||||
# choices=[(True, 'Yes'),
|
||||
# (False, 'No')])
|
||||
}
|
||||
|
||||
|
||||
ImageFormSet = inlineformset_factory(
|
||||
Rapid,
|
||||
RapidImage,
|
||||
fields=["image", "feedback_image"],
|
||||
exclude=[],
|
||||
can_delete=True,
|
||||
extra=1,
|
||||
max_num=10,
|
||||
field_classes="testing",
|
||||
)
|
||||
|
||||
AnswerFormSet = inlineformset_factory(
|
||||
Rapid,
|
||||
Answer,
|
||||
fields=["answer", "status"],
|
||||
widgets={
|
||||
"answer": Textarea(
|
||||
attrs={"required": "false", "minlength": 2, "maxlength": 500, "rows": 3}
|
||||
)
|
||||
},
|
||||
exclude=[],
|
||||
can_delete=True,
|
||||
extra=0,
|
||||
max_num=10,
|
||||
)
|
||||
|
||||
AnswerUpdateFormSet = inlineformset_factory(
|
||||
Rapid,
|
||||
Answer,
|
||||
fields=["answer", "status"],
|
||||
widgets={
|
||||
"answer": Textarea(
|
||||
attrs={"required": "false", "minlength": 2, "maxlength": 500, "rows": 3}
|
||||
)
|
||||
},
|
||||
exclude=[],
|
||||
can_delete=True,
|
||||
extra=0,
|
||||
max_num=10,
|
||||
)
|
||||
|
||||
|
||||
# This should be made generic?
|
||||
class ExamForm(ModelForm):
|
||||
class Meta:
|
||||
model = Exam
|
||||
fields = [
|
||||
"name",
|
||||
"time_limit",
|
||||
"open_access",
|
||||
"exam_mode",
|
||||
"active",
|
||||
"publish_results",
|
||||
"archive",
|
||||
]
|
||||
from django.forms import (
|
||||
Form,
|
||||
ModelForm,
|
||||
ModelMultipleChoiceField,
|
||||
ModelChoiceField,
|
||||
ChoiceField,
|
||||
CharField,
|
||||
)
|
||||
from django.forms import inlineformset_factory
|
||||
|
||||
from rapids.models import (
|
||||
Abnormality,
|
||||
Examination,
|
||||
Rapid,
|
||||
RapidCreationDefault,
|
||||
RapidImage,
|
||||
Region,
|
||||
Answer,
|
||||
CidUserAnswer,
|
||||
Exam,
|
||||
)
|
||||
|
||||
from django.contrib.admin.widgets import FilteredSelectMultiple
|
||||
from django.forms.widgets import RadioSelect, TextInput, Textarea
|
||||
|
||||
|
||||
class RapidAnswerForm(ModelForm):
|
||||
class Meta:
|
||||
model = CidUserAnswer
|
||||
fields = ("answer",)
|
||||
|
||||
|
||||
class MarkRapidQuestionForm(Form):
|
||||
# correct = forms.CharField(required=False)
|
||||
# half_correct = forms.CharField(required=False)
|
||||
# incorrect = forms.CharField(required=False)
|
||||
marked_answers = CharField(required=False)
|
||||
|
||||
|
||||
class ExaminationForm(ModelForm):
|
||||
class Meta:
|
||||
model = Examination
|
||||
fields = ["examination"]
|
||||
|
||||
|
||||
class RegionForm(ModelForm):
|
||||
class Meta:
|
||||
model = Region
|
||||
fields = ["name"]
|
||||
|
||||
|
||||
class AbnormalityForm(ModelForm):
|
||||
class Meta:
|
||||
model = Abnormality
|
||||
fields = ["name"]
|
||||
|
||||
|
||||
class RapidCreationDefaultForm(ModelForm):
|
||||
class Meta:
|
||||
model = RapidCreationDefault
|
||||
# fields = ["site"]
|
||||
exclude = ["author"]
|
||||
|
||||
|
||||
class RapidForm(ModelForm):
|
||||
|
||||
# exams = ModelMultipleChoiceField(required=False, queryset=Exam.objects.all(),widget=FilteredSelectMultiple(verbose_name="Exams", is_stacked=False))
|
||||
class Media:
|
||||
# Django also includes a few javascript files necessary
|
||||
# for the operation of this form element. You need to
|
||||
# include <script src="/admin/jsi18n"></script>
|
||||
# in the template.
|
||||
css = {
|
||||
"all": ["css/widgets.css"],
|
||||
}
|
||||
# Adding this javascript is crucial
|
||||
js = ["jsi18n.js", "tesseract.min.js"]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.user = kwargs.pop(
|
||||
"user"
|
||||
) # To get request.user. Do not use kwargs.pop('user', None) due to potential security hole
|
||||
if kwargs.get("instance"):
|
||||
# We get the 'initial' keyword argument or initialize it
|
||||
# as a dict if it didn't exist.
|
||||
initial = kwargs.setdefault("initial", {})
|
||||
# The widget for a ModelMultipleChoiceField expects
|
||||
# a list of primary key for the selected data.
|
||||
initial["exams"] = [t.pk for t in kwargs["instance"].exams.all()]
|
||||
|
||||
ModelForm.__init__(self, *args, **kwargs)
|
||||
super(RapidForm, self).__init__(*args, **kwargs)
|
||||
# self.fields['question'].widget.attrs = {'class': 'question-form', 'rows': 10, 'cols': 100}
|
||||
# self.fields['feedback'].widget.attrs = {'class': 'feedback-form', 'rows': 10, 'cols': 100}
|
||||
|
||||
self.fields["abnormality"] = ModelMultipleChoiceField(
|
||||
required=False,
|
||||
queryset=Abnormality.objects.all(),
|
||||
widget=FilteredSelectMultiple(verbose_name="Abnormality", is_stacked=False),
|
||||
)
|
||||
|
||||
self.fields["region"] = ModelMultipleChoiceField(
|
||||
required=False,
|
||||
queryset=Region.objects.all(),
|
||||
widget=FilteredSelectMultiple(verbose_name="Region", is_stacked=False),
|
||||
)
|
||||
|
||||
self.fields["examination"] = ModelMultipleChoiceField(
|
||||
queryset=Examination.objects.all(),
|
||||
widget=FilteredSelectMultiple(verbose_name="Examination", is_stacked=False),
|
||||
)
|
||||
|
||||
self.fields["laterality"] = ChoiceField(
|
||||
choices=Rapid.LATERALITY_CHOICES, required=False, widget=RadioSelect()
|
||||
)
|
||||
|
||||
if self.user.groups.filter(name="rapid_checker").exists():
|
||||
exam_queryset = Exam.objects.all()
|
||||
else:
|
||||
exam_queryset = Exam.objects.filter(
|
||||
author__id=self.user.id
|
||||
) | Exam.objects.filter(open_access=True)
|
||||
|
||||
self.fields["exams"] = ModelMultipleChoiceField(
|
||||
required=False,
|
||||
queryset=exam_queryset,
|
||||
widget=FilteredSelectMultiple(verbose_name="Exams", is_stacked=False),
|
||||
)
|
||||
|
||||
def save(self, commit=True):
|
||||
instance = ModelForm.save(self, False)
|
||||
instance.save()
|
||||
|
||||
old_exams = instance.exams.all()
|
||||
|
||||
new_exams = self.cleaned_data["exams"]
|
||||
|
||||
for exam in old_exams:
|
||||
if exam not in new_exams:
|
||||
exam.exam_questions.remove(instance)
|
||||
|
||||
for exam in new_exams:
|
||||
exam.exam_questions.add(instance)
|
||||
#exam.save()
|
||||
|
||||
# # Prepare a 'save_m2m' method for the form,
|
||||
# old_save_m2m = self.save_m2m
|
||||
#
|
||||
# def save_m2m():
|
||||
# old_save_m2m()
|
||||
# # This is where we actually link the pizza with toppings
|
||||
# instance.exams.clear()
|
||||
# for exam in self.cleaned_data["exams"]:
|
||||
# instance.exams.add(exam)
|
||||
#
|
||||
# self.save_m2m = save_m2m
|
||||
#
|
||||
# # Do we need to save all changes now?
|
||||
# # if commit:
|
||||
# instance.save()
|
||||
self.save_m2m()
|
||||
|
||||
return instance
|
||||
|
||||
class Meta:
|
||||
model = Rapid
|
||||
# fields = ['due_back']
|
||||
# fields = '__all__'
|
||||
fields = [
|
||||
"normal",
|
||||
"abnormality",
|
||||
"region",
|
||||
"laterality",
|
||||
"examination",
|
||||
# "site",
|
||||
"feedback",
|
||||
"open_access",
|
||||
]
|
||||
# fields = ['question', 'feedback', 'subspecialty', 'references']
|
||||
widgets = {
|
||||
# "normal": RadioSelect(
|
||||
# choices=[(True, 'Yes'),
|
||||
# (False, 'No')])
|
||||
}
|
||||
|
||||
|
||||
ImageFormSet = inlineformset_factory(
|
||||
Rapid,
|
||||
RapidImage,
|
||||
fields=["image", "feedback_image"],
|
||||
exclude=[],
|
||||
can_delete=True,
|
||||
extra=1,
|
||||
max_num=10,
|
||||
field_classes="testing",
|
||||
)
|
||||
|
||||
AnswerFormSet = inlineformset_factory(
|
||||
Rapid,
|
||||
Answer,
|
||||
fields=["answer", "status"],
|
||||
widgets={
|
||||
"answer": Textarea(
|
||||
attrs={"required": "false", "minlength": 2, "maxlength": 500, "rows": 3}
|
||||
)
|
||||
},
|
||||
exclude=[],
|
||||
can_delete=True,
|
||||
extra=0,
|
||||
max_num=10,
|
||||
)
|
||||
|
||||
AnswerUpdateFormSet = inlineformset_factory(
|
||||
Rapid,
|
||||
Answer,
|
||||
fields=["answer", "status"],
|
||||
widgets={
|
||||
"answer": Textarea(
|
||||
attrs={"required": "false", "minlength": 2, "maxlength": 500, "rows": 3}
|
||||
)
|
||||
},
|
||||
exclude=[],
|
||||
can_delete=True,
|
||||
extra=0,
|
||||
max_num=10,
|
||||
)
|
||||
|
||||
|
||||
# This should be made generic?
|
||||
class ExamForm(ModelForm):
|
||||
class Meta:
|
||||
model = Exam
|
||||
fields = [
|
||||
"name",
|
||||
"time_limit",
|
||||
"open_access",
|
||||
"exam_mode",
|
||||
"active",
|
||||
"publish_results",
|
||||
"archive",
|
||||
]
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
{% extends 'rapids/exams.html' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="rapids">
|
||||
<h2>Marking exam: {{ exam.name }}</h2>
|
||||
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>
|
||||
</div>
|
||||
<div id="stark-marking-button"><a href="{% url 'rapids:mark' exam_pk=exam.pk sk=0 %}"><button>Click here to start marking</button></a></div>
|
||||
|
||||
<ul id="question-mark-list">
|
||||
{% for question, unmarked_count, unmarked_count2 in question_unmarked_map %}
|
||||
<li data-markcount={{unmarked_count}} {% if unmarked_count %}class="unmarked" {% endif %}><a href="{% url 'rapids:mark' exam_pk=exam.pk sk=forloop.counter0 %}">Question {{forloop.counter }}:
|
||||
{{ question }}</a><br />Unmarked answers: {{unmarked_count}}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% extends 'rapids/exams.html' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="rapids">
|
||||
<h2>Marking exam: {{ exam.name }}</h2>
|
||||
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>
|
||||
</div>
|
||||
<div id="stark-marking-button"><a href="{% url 'rapids:mark' exam_pk=exam.pk sk=0 %}"><button>Click here to start marking</button></a></div>
|
||||
|
||||
<ul id="question-mark-list">
|
||||
{% for question, unmarked_count, unmarked_count2 in question_unmarked_map %}
|
||||
<li data-markcount={{unmarked_count}} {% if unmarked_count %}class="unmarked" {% endif %}><a href="{% url 'rapids:mark' exam_pk=exam.pk sk=forloop.counter0 %}">Question {{forloop.counter }}:
|
||||
{{ question }}</a><br />Unmarked answers: {{unmarked_count}}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
+1290
-1290
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user