带有两个外键的模型的内联表单集的问题

时间:2013-03-10 10:18:05

标签: django django-models django-forms

我在使用Inlineformsets时遇到了一些困难。我正在为我的学生编写一个数据库应用程序,我有两个主要的类:学生(姓氏,名字,电子邮件地址等)和模块(标题,代码,评估名称等)。然后我有第三节课,可以保存每个学生在他/她所在的每个模块中的表现(学生和模块被定义为unique_together):

class Performance(models.Model):
    student = models.ForeignKey(Student)
    module = models.ForeignKey(Module)
    seminar_group = models.IntegerField(blank=True, null=True)
    assessment_1 = models.IntegerField(blank=True, null=True)
    assessment_2 = models.IntegerField(blank=True, null=True)
    assessment_3 = models.IntegerField(blank=True, null=True)
    exam = models.IntegerField(blank=True, null=True)
    average = models.IntegerField(blank=True, null=True)

在模型中,我有一个保存平均值的功能(评估值可以在Module类中定义,例如,文章可能值40%,考试可能60%)

def save_with_avg(self):
    sum = 0
    if self.assessment_1:
        value = self.assessment_1 * self.module.assessment_1_value
        sum = sum + value
    if self.assessment_2:
        value = self.assessment_2 * self.module.assessment_2_value
        sum = sum + value
    if self.exam:
        value = self.exam * self.module.exam_value
        sum = sum + value
    self.average = sum / 100
    self.save()

我正在努力的是制作一个formset来编辑模块的所有特定标记。我现在这样做的方式是我在forms.py中生成一个表单类,其函数能够设置一些参数(该模块有多少评估,哪些评估应该有一个“bootstrapuneditable”小部件)。这听起来有点奇怪,但在旧版本的Django中,一个错误阻止了“小部件”作为模型形式集的参数传递,我不想冒险重写这个,如果我的webhoster选择(待定) )没有运行最新版本。)

def generate_mark_form(no_of_assessments, noexam=False, to_mark='all', *args, **kwargs):

    # Some stuff to come up with the variables exclude and widgets

    class MarkForm(forms.ModelForm):
        class Meta:
            model = Performance
            exclude = excludes
            widgets = use_widgets

    return MarkForm

然后我使用该表单类生成inlineformset:

form = generate_mark_form(no_of_assessments, noexam, assessment_to_change)
MarkFormSet = inlineformset_factory(Module, Performance, form=form)

然后我在views.py:

中以正常方式使用此MarkFormSet
if request.method == 'POST':
    formset = MarkFormSet(request.POST, instance=module)
    if formset.is_valid():
        instances = formset.save(commit=False)
        for instance in instances:
            instance.save_with_avg()
        return HttpResponseRedirect(module.get_absolute_url())
else:
    formset = MarkFormSet(instance=module)
return render_to_response(...)

然后,模板在表格中使用formset:

    <form action = "{{ action_url }}", method="post">
    {% csrf_token %}

    {{ formset.management_form }}
    {% for form in formset %}
        <tr>
            <td>
                {{ form.student }}
            </td>
            {% if current_module.assessment_1_title %}
                <td>
                    {{ form.assessment_1 }}
                </td>
            {% endif %}
            {% if current_module.assessment_2_title %}
                <td>
                    {{ form.assessment_2 }}
                </td>
            {% endif %}
            {% if current_module.assessment_3_title %}
                <td>
                    {{ form.assessment_3 }}
                </td>
            {% endif %}
            {% if current_module.exam_value %}
                <td>
                    {{ form.exam }}
                </td>
            {% endif %}
            <td>
                {{ form.average.value }}
            </td>
        </td>
    {% endfor %}

除了两件事外,一切看起来都很好:

  1. 表单显示学生姓名(在学生班级的__unicode__中设置),但作为下拉菜单。如果我将它们设置为不可编辑或使用form.student.value,我只会在HTML中获得(无用的)id号。如何在没有下拉菜单的情况下获得__unicode__函数的结果?

  2. 当我点击“提交”时,我收到“MultiValueDictKeyError:”键<'p>

  3. 中没有找到'performance_set-0-id'

    很抱歉很长的帖子,我一直在寻找解决方案,所以如果有人能指出我的错误,那就太棒了!

    谢谢!

0 个答案:

没有答案