Files
penracourses/anatomy/forms.py
T
2024-01-15 22:46:41 +00:00

234 lines
6.6 KiB
Python

from django.forms import (
Form,
ModelForm,
ModelMultipleChoiceField,
ModelChoiceField,
ChoiceField,
CharField,
)
from django.forms import inlineformset_factory
from django.contrib.postgres.forms import SimpleArrayField, SplitArrayField , SplitArrayWidget
from generic.forms import ExamAuthorFormMixin, ExamFormMixin
from .models import (
Answer,
UserAnswer,
AnatomyQuestion,
# Examination,
BodyPart,
#Structure,
Region,
Modality,
QuestionType,
Exam,
)
from generic.models import CidUserGroup, Examination
from django.contrib.admin.widgets import FilteredSelectMultiple
from django.forms.widgets import RadioSelect, TextInput, Textarea
from dal import autocomplete
from tinymce.widgets import TinyMCE
class AnatomyAnswerForm(ModelForm):
class Meta:
model = UserAnswer
fields = ("answer",)
class MarkAnatomyQuestionForm(Form):
# correct = forms.CharField(required=False)
# half_correct = forms.CharField(required=False)
# incorrect = forms.CharField(required=False)
marked_answers = CharField(required=False)
class AnatomyQuestionForm(ModelForm):
# exams = ModelMultipleChoiceField(required=False, queryset=Exam.objects.all())
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(AnatomyQuestionForm, 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["question_type"] = ModelChoiceField(
required=True,
queryset=QuestionType.objects.all(),
initial=1,
)
self.fields["region"] = ModelChoiceField(
required=False,
queryset=Region.objects.all(),
)
self.fields["modality"] = ModelChoiceField(
required=True,
queryset=Modality.objects.all(),
)
self.fields["examination"] = ModelChoiceField(
required=False,
queryset=Examination.objects.all(),
)
self.fields["body_part"] = ModelChoiceField(
required=False,
queryset=BodyPart.objects.all(),
)
#self.fields["answer_suggest_incorrect"] = CharField(max_length=255, required=False)
if self.user.groups.filter(name="anatomy_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):
# Get the unsaved Pizza instance
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)
self.save_m2m()
return instance
class Meta:
model = AnatomyQuestion
fields = [
"question_type",
"image",
"answer_help",
"answer_suggest_incorrect",
"region",
"modality",
"structure",
"feedback",
"examination",
"body_part",
"description",
"open_access",
]
widgets = {
"structure": autocomplete.ModelSelect2(url="atlas:structure-autocomplete"),
"answer_help": TinyMCE(attrs={"cols": 80, "rows": 5}),
"feedback": TinyMCE(attrs={"cols": 80, "rows": 5}),
}
class AnatomyQuestionAnswerForm(ModelForm):
class Meta:
model = AnatomyQuestion
fields = []
AnswerFormSet = inlineformset_factory(
AnatomyQuestion,
Answer,
fields=["answer", "status"],
widgets={
"answer": Textarea(
attrs={"required": "true", "minlength": 2, "maxlength": 500, "rows": 3}
)
},
exclude=[],
can_delete=True,
extra=1,
max_num=10,
)
AnswerUpdateFormSet = inlineformset_factory(
AnatomyQuestion,
Answer,
fields=["answer", "status"],
widgets={
"answer": Textarea(
attrs={"required": "true", "minlength": 2, "maxlength": 500, "rows": 3}
)
},
exclude=[],
can_delete=True,
extra=0,
max_num=10,
)
class ExaminationForm(ModelForm):
class Meta:
model = Examination
fields = ["examination"]
class BodyPartForm(ModelForm):
class Meta:
model = BodyPart
fields = ["bodypart"]
class ExamForm(ExamFormMixin, ModelForm):
class Meta(ExamFormMixin.Meta):
model = Exam
#class ExamAuthorForm(ModelForm):
# class Meta:
# model = Exam
# fields = ["author"]
#
# def __init__(self, *args, **kwargs):
# ModelForm.__init__(self, *args, **kwargs)
# self.fields["author"] = ModelMultipleChoiceField(
# queryset=User.objects.all(),
# widget=FilteredSelectMultiple(verbose_name="Authors", is_stacked=False),
# )
class ExamAuthorForm(ExamAuthorFormMixin):
class Meta(ExamAuthorFormMixin.Meta):
model = Exam