我在使用 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)
在模型中,我有一个保存平均值的功能(可以在模块类中定义评估的值,例如论文可能值 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()
我正在努力的是制作一个表单集来编辑模块的所有特定标记。我现在这样做的方式是在我的 forms.py 中生成一个表单类,该类具有能够设置一些参数的功能(该模块有多少评估,哪些评估应该有一个“bootstrapuneditable”小部件)。这听起来有点奇怪,但在旧版本的 Django 中,一个错误阻止了将“小部件”作为参数传递给模型表单集,如果我选择的虚拟主机(待定),我不想冒险重写这个) 不运行最新版本)。
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
然后我使用该表单类生成一个内联表单集:
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(...)
然后模板使用表格中的表单集:
<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 %}
一切看起来都很好,除了两件事:
该表单显示学生姓名(在
__unicode__
Student 类中设置),但作为下拉菜单。如果我将它们设置为不可编辑或改用 form.student.value,我只会在 HTML 中获得(无用的)id 号。如何在__unicode__
没有下拉菜单的情况下获得函数的结果?当我点击“提交”时,我得到一个“MultiValueDictKeyError:”Key 'performance_set-0-id' not found in
对不起,很长的帖子,我一直在寻找解决方案一段时间,所以如果有人能在这里指出我的错误,那就太好了!
谢谢!