为每个与 Django 中的另一个实例相关的模型实例创建一个表单字段
Create a field in form for each model instance related to another instance in django
我正在尝试使用 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']
您需要创建一个表单集。
好的,我会解释的。首先,您应该创建带有 question
(隐藏)和 answer
(文本)字段的表单。
class AnswerForm(forms.Form):
question = forms.ModelChoiceField(queryset=Question.objects.all(),
widget=forms.HiddenInput)
answer = forms.CharField(required=True)
接下来创建表单集,其中表单的数量等于考试中的问题数量。对于每个表格,初始 question
将是具体考试的 Question
实例。如文档中所述,表单集的处理是标准的。
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 - 为此表单集创建 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>
我正在尝试使用 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']
您需要创建一个表单集。
好的,我会解释的。首先,您应该创建带有 question
(隐藏)和 answer
(文本)字段的表单。
class AnswerForm(forms.Form):
question = forms.ModelChoiceField(queryset=Question.objects.all(),
widget=forms.HiddenInput)
answer = forms.CharField(required=True)
接下来创建表单集,其中表单的数量等于考试中的问题数量。对于每个表格,初始 question
将是具体考试的 Question
实例。如文档中所述,表单集的处理是标准的。
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 - 为此表单集创建 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>