django 具有不同问题类型和回答类型的测验应用程序的设计方法

zqry0prt  于 2023-08-08  发布在  Go
关注(0)|答案(1)|浏览(114)

我尝试实现此功能沿着用户选择问题是否是带有选项的多项选择题、带有答案字段的简答题干以及图像视频问题(其中干可以是带有字段的图像)的能力。
到目前为止:

class Question(models.Model):

    QUESTION_TYPE_CHOICES = [
        ('MCQ', 'MultipleChoiceQuestion'),
        ('SAQ', 'ShortAnswerQuestion'),
        ('IVQ', 'ImageVideoQuestion'),
    ]
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    paper = models.ForeignKey(Paper, on_delete=models.CASCADE, null=True)
    question_type = models.CharField(max_length=200,choices=QUESTION_TYPE_CHOICES, null=True) # MultipleChoiceQuestion, ShortAnswerQuestion, EssayQuestion, ImageVideoQuestion
    question_text = models.CharField(max_length=200)

    def __str__(self):
        return self.question_text
    class Meta:
        abstract = True

class MultipleChoiceQuestion(Question):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    paper = models.ForeignKey(Paper, on_delete=models.CASCADE, null=True)
    # multiple_choice_question_text = models.CharField(max_length=200)
    multiple_choice_option_text = models.CharField(max_length=200, default=None)

    def __str__(self):
        return self.question_text

class MultipleChoiceOption(models.Model):
    multiple_choice_question = models.ForeignKey(MultipleChoiceQuestion, on_delete=models.CASCADE, null=True)
    multiple_choice_option_text = models.CharField(max_length=200, default=None)
    is_correct = models.BooleanField(default=False)

    def __str__(self):
        return self.multiple_choice_option_text

# applies to short answer questions and essays
class ShortAnswerQuestion(Question):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    paper = models.ForeignKey(Paper, on_delete=models.CASCADE, null=True)
    # short_answer_question_text = models.TextField() # Text of the question
    answer_text = models.TextField() # Answer to the question
    discussion = models.TextField(blank=True) # Discussion or additional information about the question (optional)

    def __str__(self):
        return self.question_text

# applies to OSCEs, POTS or other question with an image, or a video within the stem
class ImageVideoQuestion(Question):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    paper = models.ForeignKey(Paper, on_delete=models.CASCADE, null=True)
    # image_video_question_text = models.TextField() # Text of the question
    answer_text = models.TextField() # Answer to the question
    discussion = models.TextField(blank=True) # Discussion or additional information about the question (optional)

    def __str__(self):
        return self.question_text

字符串
这三种类型的问题继承了基类Question类,该基类具有供参与者输入问题 Backbone.js 的字段。最好的解决办法是什么?
当贡献者想要添加问题时,他们应该能够选择问题的类型,并且相应的字段会自动显示。例如,选择MCQ应该会导致他们看到选项字段,他们可以在其中添加它们,并在保存之前突出显示哪个选项是正确的。如果他们选择SAQ,则向他们显示一个答案字段以插入答案。

nsc4cvqm

nsc4cvqm1#

首先,我必须提到,这是一个示例代码,应该为你工作,但你必须更新它的基础上,你的项目,使它工作顺利,我想向你展示的过程。
首先,您必须为每个问题创建ModelForm:

from django import forms
from .models import MultipleChoiceQuestion, ShortAnswerQuestion, ImageVideoQuestion

class MultipleChoiceQuestionForm(forms.ModelForm):
    class Meta:
        model = MultipleChoiceQuestion
        fields = ['question_text', 'multiple_choice_option_text']

class ShortAnswerQuestionForm(forms.ModelForm):
    class Meta:
        model = ShortAnswerQuestion
        fields = ['question_text', 'answer_text', 'discussion']

class ImageVideoQuestionForm(forms.ModelForm):
    class Meta:
        model = ImageVideoQuestion
        fields = ['question_text', 'answer_text', 'discussion']

字符串
然后创建一个表单,用户可以选择问题类型,然后向用户显示该表单:

class QuestionForm(forms.Form):
    QUESTION_TYPE_CHOICES = [
        ('MCQ', 'Multiple Choice'),
        ('SAQ', 'Short Answer'),
        ('IVQ', 'Image/Video'),
    ]

    question_type = forms.ChoiceField(choices=QUESTION_TYPE_CHOICES)
    question_form = forms.CharField(widget=forms.HiddenInput(), required=False)

    def __init__(self, *args, **kwargs):
        super(QuestionForm, self).__init__(*args, **kwargs)
        self.fields['question_type'].widget.attrs.update({'onchange': 'show_question_form();'})

        self.forms = {
            'MCQ': MultipleChoiceQuestionForm(prefix='mcq'),
            'SAQ': ShortAnswerQuestionForm(prefix='saq'),
            'IVQ': ImageVideoQuestionForm(prefix='ivq'),
        }

    def clean(self):
        cleaned_data = super(QuestionForm, self).clean()
        question_type = cleaned_data.get('question_type')

        if question_type not in self.forms.keys():
            raise forms.ValidationError('Invalid question type')

        return cleaned_data


你必须在代码中添加一个JS脚本,让用户在表单之间切换:

<!-- Your HTML template -->
<script>
    function show_question_form() {
        var questionType = document.getElementById('id_question_type').value;
        var formDivs = ['id_question_form_mcq', 'id_question_form_saq', 'id_question_form_ivq'];

        for (var i = 0; i < formDivs.length; i++) {
            document.getElementById(formDivs[i]).style.display = 'none';
        }

        if (questionType) {
            document.getElementById('id_question_form_' + questionType.toLowerCase()).style.display = 'block';
        }
    }
</script>

<form method="post">
    {% csrf_token %}
    {{ form.as_p }}

    <div id="id_question_form_mcq" style="display:none;">
        {{ form.forms.MCQ.as_p }}
    </div>
    <div id="id_question_form_saq" style="display:none;">
        {{ form.forms.SAQ.as_p }}
    </div>
    <div id="id_question_form_ivq" style="display:none;">
        {{ form.forms.IVQ.as_p }}
    </div>

    <input type="submit" value="Save">
</form>


然后,您可以在视图中这样处理表单提交:

from django.shortcuts import render

def add_question(request):
    if request.method == 'POST':
        form = QuestionForm(request.POST)
        if form.is_valid():
            question_type = form.cleaned_data['question_type']
            if question_type == 'MCQ':
                question_form = form.forms['MCQ']
            elif question_type == 'SAQ':
                question_form = form.forms['SAQ']
            elif question_type == 'IVQ':
                question_form = form.forms['IVQ']

            if question_form.is_valid():
                # Save the question and its corresponding type-specific fields
                question = form.save(commit=False)
                question.save()

                specific_question = question_form.save(commit=False)
                specific_question.question = question
                specific_question.save()

                return render(request, 'success.html')
    else:
        form = QuestionForm()

    return render(request, 'add_question.html', {'form': form})

相关问题