如何使用第二个模型中的复杂数据对 Django 模型进行排序?

发布于 2024-09-15 02:27:26 字数 3013 浏览 6 评论 0原文

我有 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)

但是现在,当涉及到对视图的输出进行排序时,我遇到两个问题:

  1. “排序”既不正确也不一致。
  2. 在排序过程中,我丢失了战斗机的名字

这是当前的代码(如果不执行排序,输出是正确的):

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:

  1. The "sort" is neither correct nor consistent.
  2. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

嘦怹 2024-09-22 02:27:26

我已经成功解决了这两个问题:

  1. 我附加的是胜利的集合,而不是该列表的“长度”。
    我需要改变这个:

    wins.append((fighter.id, get_fighter_wins(fighter)),)

    至:

    wins.append((fighter.id, len(get_fighter_wins(fighter))),)

  2. 我正在构造一个查询集列表,而不是对象列表。
    我需要改变这个:

    winners.append(Fighter.objects.filter(id=win[0]))

    至:

    winners.append(Fighter.objects.get(id=win[0]))

(为我的朋友阿提拉干杯谁向我解释了第二个问题。)

顺便说一句,我的最终代码不使用三个单独的函数。相反,我这样做了:

    .
    .
    .

class WeightGroup:
    .
    .
    .
            def sort (self, sort_function):
                scores = []
                scorers = []

                for fighter in self.fighters:
                    scores.append((fighter.id, len(sort_function(fighter))),)
                for score in (sorted(scores, key=lambda f: f[1], reverse=True)):
                    scorers.append(Fighter.objects.get(id=score[0])) 

                self.fighters = scorers
    .
    .
    .
        if sort in ['wins', 'losses', 'draws']:
            title += ', sorted by ' + sort
            for weight_group in weight_groups:
                if (sort == 'wins'): weight_group.sort(get_fighter_wins)
                if (sort == 'losses'): weight_group.sort(get_fighter_losses)
                if (sort == 'draws'): weight_group.sort(get_fighter_draws)
    .
    .
    .

I've managed to solve both problems:

  1. 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))),)

  2. 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:

    .
    .
    .

class WeightGroup:
    .
    .
    .
            def sort (self, sort_function):
                scores = []
                scorers = []

                for fighter in self.fighters:
                    scores.append((fighter.id, len(sort_function(fighter))),)
                for score in (sorted(scores, key=lambda f: f[1], reverse=True)):
                    scorers.append(Fighter.objects.get(id=score[0])) 

                self.fighters = scorers
    .
    .
    .
        if sort in ['wins', 'losses', 'draws']:
            title += ', sorted by ' + sort
            for weight_group in weight_groups:
                if (sort == 'wins'): weight_group.sort(get_fighter_wins)
                if (sort == 'losses'): weight_group.sort(get_fighter_losses)
                if (sort == 'draws'): weight_group.sort(get_fighter_draws)
    .
    .
    .
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文