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我更新了我的答案,请查看:) –

相关问题