0

わかりました、これは多かれ少なかれ「テーブルに2つの外部キー、行にkey1、列にkey2を持つスパースデータを提示する」です。よくあることだと思いますが、少しひねりがあります。

Django では、学生グループの学期の成績を含むページを作成する必要があります。次のようになります。

          暗号入門 | 離散数学 | ...
         Chkpt1 Chkpt2 Chkpt3 | Chkpt1 Chkpt1 Chkpt2 Chkpt3 | Chkpt1 ...
アリス 15 26 47 | 10 20 - | ...
ボブ 25 54 73 | 25 54 - | ...  
チャック 33 66 99 | 33 60 - | ...     
...

グループ内の学生はすべて同じコースを受講し、学校は各学期中にすべてのインストラクターがスコアを報告する 3 つのチェックポイントを定義しています。講師がまだスコアを提出していない場合、一部の列はまだ入力されていない可能性があります (上記の例では、離散数学の Chkpt3)。

Grade のモデルは、Student、Course、および Checkpoint を参照します。チェックポイントは学期を参照します。学生はグループを参照します。

問題は、テンプレートにデータを渡す方法です。DBからデータを取得します

reportgrades = Grade.objects.filter(student__group__id=group_id, 
                                    checkpoint__semester=semester)

その後私は:

  1. gr[studid][courseid][chkptid]ネストされたループでネストされた dict を作成し、ダッシュで埋めます。
  2. ループしreportgradesてこの dict に値を入力し、成績が存在するダッシュを上書きします。

    no_grade = u'—'
    grades = {}
    for student in students:
        grades[student.id] = {}
        for course in courses:
            grades[student.id][course.id] = {}
            for chkpt in checkpoints:
                grades[student.id][course.id][chkpt.id] = no_grade
    
    for g in reportgrades:
        grades[g.student.id][g.course.id][g.checkpoint.id] = g.points
    
  3. これらを抽出するカスタム テンプレート タグを作成し、

    @register.filter
    def getitem ( item, param1 ):
        return item.get(param1)
    
  4. forテンプレートの 3 ネスト内でこれを使用します

    {% for s in students %}
    <tr>
        <td>{{ s }}</td>
        {% for c in courses %}
            {% for tp in test_periods %}
            <td>{{ grades| getitem:s.id | getitem:c.id | getitem:tp.id }}</td>
            {% endfor %}
        {% endfor %}
    </tr>
    {% endfor %}
    

単純なテーブルを作成するのは大変ですよね。サイズ 3 x NUM_STUDENTS x NUM_COURSES の線形リストを検討しました。あまりきれいでもありません。より良い方法は?

4

1 に答える 1

1

RickyA が提案するように、テンプレート コードはできるだけシンプルにしてください。代わりに、ビューで複雑なデータ変換を行ってください。

トップとサイドにヘッダーがあるので、これらを独自のリストに保存します。次に、実際のデータをリストのリストに保存します。たとえば、ビュー コードでは次のようになります。

student = Student.objects.all()
context['classes'] = [class.name for class in Class.objects.all()]
context['checkPoints'] = range(1, 4)
context['data'] = ... 

(code to flatten checkpoints for each students in to flat list, 
then make list of these lists, don't forget to add the student 
name as the first item in each row)

そして、あなたのテンプレートでは、次のようなことをします

<table>
<thead>
<tr>
<th></th>
{% for class in classes %}
<th colspan="3">{{ class }}</th>
{% endfor %}
</tr>
<!-- something similar for checkpoints -->
</thead>
<tbody>
{% for row in data %}
<tr>
{% for item in row %}
{% if not forloop.counter0 %}
<th>{{ item }}</th>
{% else %}
<td>{{ item }}</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>

これは有効な Django テンプレート コードだと思います。私は最近 Jinja2 を使用しているので、動作しない機能を追加した場合は申し訳ありませんが、問題ないはずです。

于 2012-11-30T12:01:54.273 に答える