0

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 つの点を除いて、すべて問題ないように見えます。

  1. フォームには、( __unicode__Student クラスで設定されているように) 生徒の名前が表示されますが、ドロップダウン メニューとして表示されます。それらを編集不可として設定するか、代わりに form.student.value を使用すると、HTML で (役に立たない) ID 番号しか取得できません。ドロップダウンメニューなしで関数の結果を取得するにはどうすればよいです__unicode__か??

  2. 現時点で「送信」をクリックすると、「MultiValueDictKeyError: "Key 'performance_set-0-id' not found in

非常に長い投稿で申し訳ありません。私はしばらくの間解決策を探していたので、誰かがここで私のエラーを指摘してくれたら素晴らしいと思います!

ありがとう!

4

0 に答える 0