如何使用第二个模型中的复杂数据对 Django 模型进行排序?
我有 3 个 django 模型(本例已简化):
class Fighter (models.Model):
name = models.CharField(max_length=100)
weight_class = models.ForeignKey(WeightClass, related_name="fighter_weight_class")
class Bout (models.Model):
fighter_1 = models.ForeignKey(Fighter, related_name="bout_fighter_1")
fighter_2 = models.ForeignKey(Fighter, related_name="bout_fighter_2")
winner = models.ForeignKey(Fighter, related_name="bout_winner", blank=True,
null=True, help_text='Leave blank for draw.')
date = models.DateField()
cancelled = models.BooleanField()
class WeightClass (models.Model):
name = models.CharField(max_length=100)
我希望能够按战士的统计数据列出它们。我创建了这些 函数(有效)来计算他们的胜利、损失和平局:
def get_bouts_with_fighter (fighter):
return Bout.objects.filter(fighter_1 = fighter) | \
Bout.objects.filter(fighter_2 = fighter)
def get_fighter_wins (fighter):
return Bout.objects.filter(winner=fighter)
def get_bouts_fought_not_won (fighter):
return get_bouts_with_fighter(fighter) \
.exclude(cancelled=True) \
.exclude(date__gt = datetime.datetime.now())
def get_fighter_losses (fighter):
return get_bouts_fought_not_won(fighter)\
.exclude(winner=fighter)\
.exclude(winner=None)
def get_fighter_draws (fighter):
return get_bouts_fought_not_won(fighter)\
.filter(winner=None)
但是现在,当涉及到对视图的输出进行排序时,我遇到两个问题:
- “排序”既不正确也不一致。
- 在排序过程中,我丢失了战斗机的名字
这是当前的代码(如果不执行排序,输出是正确的):
def list(request, sort=None):
class WeightGroup:
"""
Internal class to keep data organized by weight class.
"""
weight_class = None
fighters = None
def win_sort (self):
wins = []
winners = []
for fighter in self.fighters:
wins.append((fighter.id, get_fighter_wins(fighter)),)
for win in (sorted(wins, key=lambda f: f[1], reverse=True)):
winners.append(Fighter.objects.filter(id=win[0])) #build winner list by score
self.fighters = winners
def loss_sort (self):
#TO DO:
pass
def draw_sort (self):
#TO DO:
pass
title = 'Fighters'
weight_groups = []
for weight_class in WeightClass.objects.all():
weight_group = WeightGroup()
weight_group.weight_class = weight_class
weight_group.fighters = Fighter.objects.filter(weight_class=weight_class)
weight_groups.append(weight_group)
if sort in ['wins', 'losses', 'draws']:
title += ', sorted by ' + sort
for weight_group in weight_groups:
if (sort == 'wins'): weight_group.win_sort()
if (sort == 'losses'): weight_group.loss_sort()
if (sort == 'draws'): weight_group.draw_sort()
return render_to_response ('fighters/list.html',{
'title': title,
'weight_groups':weight_groups
})
任何关于如何让它工作的建议将不胜感激!
I have 3 django models (simplified for this example):
class Fighter (models.Model):
name = models.CharField(max_length=100)
weight_class = models.ForeignKey(WeightClass, related_name="fighter_weight_class")
class Bout (models.Model):
fighter_1 = models.ForeignKey(Fighter, related_name="bout_fighter_1")
fighter_2 = models.ForeignKey(Fighter, related_name="bout_fighter_2")
winner = models.ForeignKey(Fighter, related_name="bout_winner", blank=True,
null=True, help_text='Leave blank for draw.')
date = models.DateField()
cancelled = models.BooleanField()
class WeightClass (models.Model):
name = models.CharField(max_length=100)
I would like to be able to list the Fighters by their stats. I created these
functions (which work) to calculate their wins, losses, and draws:
def get_bouts_with_fighter (fighter):
return Bout.objects.filter(fighter_1 = fighter) | \
Bout.objects.filter(fighter_2 = fighter)
def get_fighter_wins (fighter):
return Bout.objects.filter(winner=fighter)
def get_bouts_fought_not_won (fighter):
return get_bouts_with_fighter(fighter) \
.exclude(cancelled=True) \
.exclude(date__gt = datetime.datetime.now())
def get_fighter_losses (fighter):
return get_bouts_fought_not_won(fighter)\
.exclude(winner=fighter)\
.exclude(winner=None)
def get_fighter_draws (fighter):
return get_bouts_fought_not_won(fighter)\
.filter(winner=None)
But now, when comes to sorting the output for the view, I'm having two problems:
- The "sort" is neither correct nor consistent.
- During the sort, I'm losing the fighter's name
Here is the current code (the output is correct if no sorting is performed):
def list(request, sort=None):
class WeightGroup:
"""
Internal class to keep data organized by weight class.
"""
weight_class = None
fighters = None
def win_sort (self):
wins = []
winners = []
for fighter in self.fighters:
wins.append((fighter.id, get_fighter_wins(fighter)),)
for win in (sorted(wins, key=lambda f: f[1], reverse=True)):
winners.append(Fighter.objects.filter(id=win[0])) #build winner list by score
self.fighters = winners
def loss_sort (self):
#TO DO:
pass
def draw_sort (self):
#TO DO:
pass
title = 'Fighters'
weight_groups = []
for weight_class in WeightClass.objects.all():
weight_group = WeightGroup()
weight_group.weight_class = weight_class
weight_group.fighters = Fighter.objects.filter(weight_class=weight_class)
weight_groups.append(weight_group)
if sort in ['wins', 'losses', 'draws']:
title += ', sorted by ' + sort
for weight_group in weight_groups:
if (sort == 'wins'): weight_group.win_sort()
if (sort == 'losses'): weight_group.loss_sort()
if (sort == 'draws'): weight_group.draw_sort()
return render_to_response ('fighters/list.html',{
'title': title,
'weight_groups':weight_groups
})
Any suggestions how I can get this to work will be appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我已经成功解决了这两个问题:
我附加的是胜利的集合,而不是该列表的“长度”。
我需要改变这个:
wins.append((fighter.id, get_fighter_wins(fighter)),)
至:
wins.append((fighter.id, len(get_fighter_wins(fighter))),)
我正在构造一个查询集列表,而不是对象列表。
我需要改变这个:
winners.append(Fighter.objects.filter(id=win[0]))
至:
winners.append(Fighter.objects.get(id=win[0]))
(为我的朋友阿提拉干杯谁向我解释了第二个问题。)
顺便说一句,我的最终代码不使用三个单独的函数。相反,我这样做了:
I've managed to solve both problems:
I was appending the collection of wins, not the "length" of that list.
I needed to change this:
wins.append((fighter.id, get_fighter_wins(fighter)),)
to:
wins.append((fighter.id, len(get_fighter_wins(fighter))),)
I was constructing a list of querysets, not a list of objects.
I needed to change this:
winners.append(Fighter.objects.filter(id=win[0]))
to:
winners.append(Fighter.objects.get(id=win[0]))
(Cheers to my friend Attila who explained the second issue to me.)
BTW, my final code doesn't use three separate functions. Instead I did this: