在与django中的另一个实例相关的每个模型实例的表单中创建一个字段 [英] Create a field in form for each model instance related to another instance in django

查看:120
本文介绍了在与django中的另一个实例相关的每个模型实例的表单中创建一个字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆