Inlineformsets で少し苦労しています。私は学生用のデータベースアプリケーションを作成しています.2つのメインクラスがあります.Student(姓、名、電子メールアドレスなど)とModule(タイトル、コード、評価の名前など)です。次に、各生徒のパフォーマンスを各モジュールに保存できるようにするための 3 番目のクラスがあります (生徒とモジュールは 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()
私が苦労しているのは、モジュールのすべての特定のマークを編集するためのフォームセットを作成することです。私が現在行っている方法は、いくつかのパラメーターを設定できる関数を使用して、forms.py にフォーム クラスを生成することです (そのモジュールの評価の数、どの評価に「ブートストラップ編集可能」ウィジェットが必要か)。これは少し奇妙に聞こえますが、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
次に、そのフォーム クラスを使用して 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(...)
次に、テンプレートはテーブルでフォームセットを使用します。
<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 %}
次の 2 つの点を除いて、すべて問題ないように見えます。
フォームには、(
__unicode__
Student クラスで設定されているように) 生徒の名前が表示されますが、ドロップダウン メニューとして表示されます。それらを編集不可として設定するか、代わりに form.student.value を使用すると、HTML で (役に立たない) ID 番号しか取得できません。ドロップダウンメニューなしで関数の結果を取得するにはどうすればよいです__unicode__
か??現時点で「送信」をクリックすると、「MultiValueDictKeyError: "Key 'performance_set-0-id' not found in
非常に長い投稿で申し訳ありません。私はしばらくの間解決策を探していたので、誰かがここで私のエラーを指摘してくれたら素晴らしいと思います!
ありがとう!