我有2个模特' 会员'和' 活动'。 他们在“很多人”中。关系。
现在我想创建一个视图,显示每个成员在一个事件时和不在时,在这样的html表中显示:
Name Event1 Event2 Event3 ...
Member1 x x ...
Member2 x x x ...
Member3 x x
Member4 x x ...
.
.
.
等等。
现在问题是事件的数量在不断增加。 我唯一的想法是在视图中创建一个html表,但这不是最优的。
是否有可能手动创建查询集,其中首先包含一个成员,然后是所有事件,然后是下一个成员,然后是所有事件?等等.. 或者有一个由Django管理的真正简单方法来访问模板中的manytomany字段
进一步参考我的模型:
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 :(得分: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可能与成员不同)