start setting up shorts
This commit is contained in:
+251
@@ -0,0 +1,251 @@
|
||||
from django.forms import (
|
||||
Form,
|
||||
ModelForm,
|
||||
ModelMultipleChoiceField,
|
||||
ModelChoiceField,
|
||||
ChoiceField,
|
||||
CharField,
|
||||
)
|
||||
from django.forms import inlineformset_factory
|
||||
from generic.forms import ExamAuthorFormMixin, ExamFormMixin, ExamGroupsFormMixin, ExamMarkerFormMixin
|
||||
|
||||
from shorts.models import (
|
||||
Abnormality,
|
||||
Examination,
|
||||
Question,
|
||||
QuestionImage,
|
||||
Region,
|
||||
SampleAnswer,
|
||||
UserAnswer,
|
||||
Exam,
|
||||
)
|
||||
|
||||
from django.contrib.admin.widgets import FilteredSelectMultiple
|
||||
from django.forms.widgets import RadioSelect, TextInput, Textarea
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from crispy_forms.helper import FormHelper
|
||||
from crispy_forms.layout import Submit, Layout, Div, Field, HTML
|
||||
from crispy_forms.bootstrap import InlineRadios
|
||||
|
||||
|
||||
class QuestionAnswerForm(ModelForm):
|
||||
class Meta:
|
||||
model = UserAnswer
|
||||
fields = ("answer",)
|
||||
|
||||
|
||||
class MarkQuestionForm(Form):
|
||||
# correct = forms.CharField(required=False)
|
||||
# half_correct = forms.CharField(required=False)
|
||||
# incorrect = forms.CharField(required=False)
|
||||
marked_answers = CharField(required=False)
|
||||
|
||||
|
||||
class QuestionAnswerForm(ModelForm):
|
||||
class Meta:
|
||||
model = Question
|
||||
fields = []
|
||||
|
||||
class QuestionForm(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", "js/upload_form_helpers.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(QuestionForm, self).__init__(*args, **kwargs)
|
||||
|
||||
|
||||
self.helper = FormHelper()
|
||||
self.helper.form_id = 'id-anatomy-question-form'
|
||||
self.helper.form_tag = False
|
||||
|
||||
self.helper.layout = Layout(
|
||||
Div(
|
||||
HTML("<h4 class='clearfix' id='abnormality-label'>Abnormality</h4>"),
|
||||
Field('abnormality', css_class='form-control'),
|
||||
HTML("<h4 class='clear-both' id='region-label'>Region</h4>"),
|
||||
Field('region', css_class='form-control'),
|
||||
css_class='clearfix abnormal-fields'
|
||||
),
|
||||
HTML("<h4 class='clear-both' id='examination-label'>Examination*</h4>"),
|
||||
Field('examination', css_class='form-control'),
|
||||
Div(InlineRadios('laterality', css_class='form-control'), css_class='clearfix clear-both'),
|
||||
Field('history', css_class='form-control'),
|
||||
Field('feedback', css_class='form-control'),
|
||||
Field('open_access', css_class='form-control'),
|
||||
HTML("<h4 class='clear-both' id='exams-label'>Exams</h4>"),
|
||||
Field('exams', css_class='form-control'),
|
||||
)
|
||||
|
||||
self.fields["abnormality"] = ModelMultipleChoiceField(
|
||||
required=False,
|
||||
queryset=Abnormality.objects.all(),
|
||||
widget=FilteredSelectMultiple(verbose_name="Abnormality", is_stacked=False),
|
||||
)
|
||||
self.fields["abnormality"].label = ""
|
||||
|
||||
self.fields["region"] = ModelMultipleChoiceField(
|
||||
required=False,
|
||||
queryset=Region.objects.all(),
|
||||
widget=FilteredSelectMultiple(verbose_name="Region", is_stacked=False),
|
||||
)
|
||||
self.fields["region"].label = ""
|
||||
|
||||
self.fields["examination"] = ModelMultipleChoiceField(
|
||||
queryset=Examination.objects.all(),
|
||||
widget=FilteredSelectMultiple(verbose_name="Examination", is_stacked=False),
|
||||
)
|
||||
self.fields["examination"].label = ""
|
||||
|
||||
self.fields["laterality"] = ChoiceField(
|
||||
choices=Question.LATERALITY_CHOICES, required=False, widget=RadioSelect()
|
||||
)
|
||||
|
||||
if self.user.groups.filter(name="shorts_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.distinct(),
|
||||
widget=FilteredSelectMultiple(verbose_name="Exams", is_stacked=False),
|
||||
)
|
||||
self.fields["exams"].label = ""
|
||||
|
||||
self.fields["history"].widget = Textarea(
|
||||
attrs={"required": "false", "minlength": 2, "maxlength": 500, "rows": 1}
|
||||
)
|
||||
|
||||
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 = Question
|
||||
# fields = ['due_back']
|
||||
# fields = '__all__'
|
||||
fields = [
|
||||
"abnormality",
|
||||
"region",
|
||||
"laterality",
|
||||
"examination",
|
||||
# "site",
|
||||
"feedback",
|
||||
"history",
|
||||
"open_access",
|
||||
]
|
||||
# fields = ['question', 'feedback', 'subspecialty', 'references']
|
||||
|
||||
ImageFormSet = inlineformset_factory(
|
||||
Question,
|
||||
QuestionImage,
|
||||
fields=["image", "feedback_image", "filename", "description"],
|
||||
exclude=[],
|
||||
can_delete=True,
|
||||
extra=1,
|
||||
max_num=10,
|
||||
)
|
||||
|
||||
#AnswerFormSet = inlineformset_factory(
|
||||
# Question,
|
||||
# SampleAnswer,
|
||||
# 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(
|
||||
# Question,
|
||||
# SampleAnswer,
|
||||
# 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(ExamFormMixin, ModelForm):
|
||||
class Meta(ExamFormMixin.Meta):
|
||||
model = Exam
|
||||
|
||||
class ExamAuthorForm(ExamAuthorFormMixin):
|
||||
class Meta(ExamAuthorFormMixin.Meta):
|
||||
model = Exam
|
||||
|
||||
class ExamMarkerForm(ExamMarkerFormMixin):
|
||||
class Meta(ExamMarkerFormMixin.Meta):
|
||||
model = Exam
|
||||
|
||||
class ExamGroupsForm(ExamGroupsFormMixin):
|
||||
class Meta(ExamGroupsFormMixin.Meta):
|
||||
model = Exam
|
||||
Reference in New Issue
Block a user