在与django中的另一个实例相关的每个模型实例的表单中创建一个字段 [英] Create a field in form for each model instance related to another instance in django
问题描述
现在我想创建表单,用户可以在其中回答问题。所以我想要一个字段为每个问题。如何创建这样的表单?
UPD :以下是我的考试和问题模型代码
$来自django.db导入模型的
从django.utils导入时区
从django_jalali.db导入模型中的
作为jmodels
从django。 utils.translation import ugettext as _
from django.core.exceptions import ValidationError
from users.models import Member
#在这里创建你的模型。
class Exam(models.Model):
name = models.CharField(max_length = 500,verbose_name = _(Exam's name))
start_date = models.DateTimeField(_(开始日期))
end_date = models.DateTimeField(_(End Date)
class Meta:
verbose_name = _(考试)
verbose_name_plural = _(考试)
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#考试尚未开始
elif timezone.now()> = self.end_date:
返回1#考试已经结束
其他:
return 0#考试正在运行
class问题(models.Model):
exam = models.ForeignKey(Exam,verbose_name = _( )
order = models.IntegerField(unique = True,
verbose_name = _(问题索引),
help_text = _(将根据其索引显示问题这个索引显示在考试页面中的问题号码))
statement = models.CharField(max_length = 10000,verbose_name = _(Question's Statement))
def __unicode __ )
return self.exam.name + - + _(Question#)+ str(self.order)
class Meta:
verbose_name = _( 问题)
verbose_name_plural = _(问题)
ordering = ['order']
您需要创建一个表单。
好的,我会解释一下。首先,您应该使用问题
(隐藏)和答案
(文本)字段创建表单。
class AnswerForm(forms.Form):
question = forms.ModelChoiceField(queryset = Question。 object.all(),
widget = forms.HiddenInput)
answer = forms.CharField(required = True)
下一步创建表单数量等于考试中的问题数量。对于每个表单,初始问题
将是具体考试的问题
实例。表单集的处理是文档中描述的标准。
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)
如果formset.is_valid():
表单中的表单:
question = form.initial ['question']
answer = form.cleaned_data ['answer']
#保存这里的答案
返回重定向('exam_done')
else:
formset = AnswerFormS et(initial = initial)
return render(request,'app / pass_exam.html',
{'exam':exam,'formset':formset})
Ans last - 为此表单集创建 pass_exam.html
模板:
< h1> {{exam}}< / h1>
< form action =。方法= POST >
{%csrf_token%}
{{formset.management_form}}
{{formset.non_form_errors}}
{form for 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>
I'm trying to write an exam system using django. I have two models. Exam, Question.
Now I want to create form in which user will be able to answer the questions. So I want a field for every question. how can I create such a form?
UPD: Below is my code for Exam and Question models
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']
You need to create a formset.
Ok, I'll explain. First you should create Form with question
(hidden) and answer
(text) fields.
class AnswerForm(forms.Form):
question = forms.ModelChoiceField(queryset=Question.objects.all(),
widget=forms.HiddenInput)
answer = forms.CharField(required=True)
Next create formset with number of forms equal to the number of questions in exam. For each form initial question
will be concrete exam's Question
instance. Handling of the formset is standard as described in the documentation.
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 - create pass_exam.html
template for this formset:
<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中的另一个实例相关的每个模型实例的表单中创建一个字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!