在表单中为与django中的另一个实例相关的每个模型实例创建一个字段

时间:2015-01-08 01:30:38

标签: django django-forms

我正在尝试使用django编写考试系统。我有两个型号。考试,问题。

现在我想创建一个用户可以回答问题的表单。所以我希望每个问题都有一个字段。我怎样才能创建这样的表格?

UPD :以下是我的考试和问题模型代码

from django.db import models
from django.utils import timezone
from django_jalali.db import models as jmodels
from django.utils.translation import ugettext as _
from django.core.exceptions import ValidationError
from users.models import Member

# Create your models here.


class Exam(models.Model):
    name = models.CharField(max_length=500, verbose_name=_("Exam's name"))
    start_date = models.DateTimeField(_("Start Date"))
    end_date = models.DateTimeField(_("End Date"))

    class Meta:
        verbose_name = _("Exam")
        verbose_name_plural = _("Exams")

    def __unicode__(self):
        return self.name
    def stage(self):
        #raise ValueError("%d", self.end_date, datetime.now())
        if timezone.now() < self.start_date:
            return -1  # exam hasn't started yet
        elif timezone.now() >= self.end_date:
            return 1  # exam has ended
        else:
            return 0  # exam is running


class Question(models.Model):
    exam = models.ForeignKey(Exam, verbose_name=_("Related exam"))
    order = models.IntegerField(unique=True,
                                verbose_name=_("Question's index"),
                                help_text=_("Questions will be shown based on their index. Also this index is shown as the question's number in exam page"))
    statement = models.CharField(max_length=10000, verbose_name=_("Question's Statement"))

    def __unicode__(self):
        return self.exam.name + " - " + _("Question #") + str(self.order)

    class Meta:
        verbose_name = _("Question")
        verbose_name_plural = _("Questions")
        ordering = ['order']

1 个答案:

答案 0 :(得分:0)

您需要创建一个formset。

好的,我会解释一下。首先,您应该使用question(隐藏)和answer(文本)字段创建表单。

class AnswerForm(forms.Form):

    question = forms.ModelChoiceField(queryset=Question.objects.all(),
                                      widget=forms.HiddenInput)
    answer = forms.CharField(required=True)

接下来创建一个formset,其中包含的表单数量等于考试中的问题数量。对于每个表单,初始question将是具体考试的Question实例。如同文档中所述,处理formset是标准的。

def pass_exam(request, exam_id):
    exam = get_object_or_404(Exam, pk=exam_id)
    questions = exam.question_set.all()
    num_questions = questions.count()
    AnswerFormSet = formset_factory(AnswerForm,
                                    max_num=num_questions, validate_max=True,
                                    min_num=num_questions, validate_min=True)
    initial = [{'question': q} for q in questions]
    if request.method == 'POST':
        formset = AnswerFormSet(request.POST, initial=initial)
        if formset.is_valid():
            for form in formset:
                question = form.initial['question']
                answer = form.cleaned_data['answer']
                # SAVE THE ANSWER HERE
            return redirect('exam_done')
    else:
        formset = AnswerFormSet(initial=initial)
    return render(request, 'app/pass_exam.html',
                  {'exam': exam, 'formset': formset})

Ans last - 为此formset创建pass_exam.html模板:

<h1>{{ exam }}</h1>

<form action="." method="POST">

    {% csrf_token %}
    {{ formset.management_form }}
    {{ formset.non_form_errors }}

    {% for form in formset %}
        <p>
            {{ form.initial.question.statement }}<br />
            {{ form.question }}
            {{ form.answer }}
            {% if form.errors %}
                {{ form.answer.errors }}
                {{ form.question.errors }}
            {% endif %}
        </p>
    {% endfor %}

    <button type="submit">Submit</button>

</form>