0

我有一個2模特'會員'和'事件'。 他們處於'ManyToMany'關係。如何在Django模板中將相關的多對多字段顯示爲表格?

現在我想創建一個視圖,顯示每個成員,當時他是一個事件,不用時,在一個HTML表這樣的:

Name Event1 Event2 Event3 ... 
Member1 x     x  ... 
Member2 x   x   x  ... 
Member3 x   x 
Member4    x   x  ... 
    . 
    . 
    . 

等。

現在問題是事件數量不斷增加。 我唯一的想法是在視圖中創建一個html表格,但這不是非常優化的。

有沒有可能手動創建查詢集,其中包含第一個成員,然後所有事件跟隨,然後下一個成員,再次是所有事件?等.. 還是有通過Django的管理方式來訪問模板

進一步參考多對多領域的真正簡單的方法在這裏我的模型:

class Member(models.Model): 
    KAPELLMEISTER='KM' 
    FLOETE='FL' 
    KLARINETTE='KL' 
    SAXOPHON='SX' 
    FLUEGELHORN='FH' 
    TENORHORN='TH' 
    HORN='HR' 
    TROMPETE='TR' 
    POSAUNE='PS' 
    TUBA='TU' 
    SCHLAGZEUG='SZ' 

    INSTRUMENTS=(
       (KAPELLMEISTER,'Kapellmeister'), 
       (FLOETE,'Floete'), 
       (KLARINETTE,'Klarinette'), 
       (SAXOPHON,'Saxophon'), 
       (FLUEGELHORN,'Fluegelhorn'), 
       (TENORHORN,'Tenorhorn'), 
       (HORN,'Horn'), 
       (TROMPETE,'Trompete'), 
       (POSAUNE,'Posaune'), 
       (TUBA,'Tuba'), 
       (SCHLAGZEUG,'Schlagzeug') 
       ) 


    name = models.CharField('Name',max_length=200) 
    instrument = models.CharField('Instrument', 
            max_length=2, 
            choices=INSTRUMENTS, 
            null=False) 
    bool_musikschueler = models.BooleanField('Musikschueler') 
    bool_student = models.BooleanField('Student') 

    def __unicode__(self): 
     return self.name 

    @classmethod 
    def create(cls, name, instrument, musikschueler, student): 
     member = cls(name=name, instrument=instrument, bool_musikschueler=musikschueler, bool_student = student) 
    return member 


class Event(models.Model): 
    PROBE='PR' 
    BEGRAEBNIS='BG' 
    MARSCHMUSIK='MM' 
    KONZERT='KO' 
    WECKRUF='WR' 

    TYPES=(
      (PROBE,'Probe'), 
      (BEGRAEBNIS,'Begraebnis'), 
      (MARSCHMUSIK,'Marschmusik'), 
      (KONZERT,'Konzert'), 
      (WECKRUF,'Weckruf') 
     ) 

    date = models.DateField('Datum') 
    type = models.CharField(max_length=2, 
          choices=TYPES, 
          default=PROBE) 
    description = models.TextField(max_length=200, blank=True) 
    anwesend = models.ManyToManyField(Member)#TODO: Widget fuer Django Admin aendern 

    def __unicode__(self): 
     return str(self.date.strftime("%Y-%m-%d"))+" , "+self.type 

    @classmethod 
    def create(cls, date, type, description): 
     event = cls(date=date, type=type, description=description) 
     return event 

和我的HTML模板:

<table> 
<tr><th>Name</th> 
{% for event in all_events %} 
    <th>{{event}}</th> 
    {% endfor %} 
</tr> 
    {% for member in all_members %} 
    <tr> 
     <td>{{ member.name }}</td> 
     <td>{{ event.anwesend }}</td> 
    </tr> 
    {% endfor %} 
</table> 

和我的實驗看法:

def statistiken(request): 
    all_members = Member.objects.all() 
    all_events = Event.objects.all() 
    for member in all_members: 
     anwesend=member.name+": " 
     for event in member.event_set.all(): 
      anwesend+=str(event) 
      print(anwesend) 

    context = {'all_members': all_members, 
       'all_events' : all_events} 
    return render(request, 'anwesenheitsapp/statistiken.html', context) 

回答

0

更新涉及您的評論:

from itertools import count, repeat 

def statistiken(request): 
    # Get all members 
    members = Member.objects.all() 

    # Get maximum number of related events 
    max_n_events = max(member.event_set.all().count() for member in members) 

    # Create a list to hold table data 
    table_data = [] 
    for member in members: 
     # Get all related events for the member 
     events = member.event_set.all() 
     # Get number of events 
     n = events.count() 

     # Append a iterator with member instance, event instances, and 
     # repeating empty strings to fill up the table 
     table_data.append(chain([member], events, repeat('', max_n_events-n))) 

    context = {'table_data': table_data} 
    return render(request, 'anwesenheitsapp/statistiken.html', context) 

和你的模板,以這樣的:

<table> 
<tr> 
{% for row in table_data %} 
    {% for col in row %} 
     <td>{{ col }}</td> 
    {% endfor %} 
{% endfor %} 
</tr> 
</table> 

下表中的字符串將是__unicode__()爲你的會員和事件,其次是空單元格的結果。


(舊答案)

要訪問一個成員實例的所有相關活動,使用event_set.all()

您的模板可以是這個樣子:

<table> 
{% for member in all_members %} 
    <td>{{ member }}</td> 
    {% for event in member.event_set.all %} 
     <td>{{ event }}</td> 
    {% endfor %} 
{% endfor %} 
</table> 

應能提供此表

| member0 | related_event00 | related_event01 | ... | related_event_0n| 
| member1 | related_event10 | related_event11 | ... | related_event_1n| 
| .... | 
| memberm | related_eventm0 | related_eventm1 | ... | related_event_mn| 

(N可能是從成員不同,以當然成員)

+0

我固定一個小在Django模板中使用拼寫錯誤 - 方法調用不應該包含括號 –

+0

謝謝,但是當成員實例在ManyToMany字段中沒有條目時,是否有插入空格的方法的事件? – jteichert

+0

@jteichert我更新了我的答案,請查看:) –

相關問題