在保存之前,需要检查外键引用特定对象

时间:2014-09-11 15:14:27

标签: python django validation model

我是Django的新手(以及一般的Python)并且有一个模型验证问题。

我有2个模特,团队和游戏。 2个团队在游戏中玩,获胜者字段可以为空/空:

class Team(models.Model):
    abbreviation = models.CharField(max_length=5, unique=True)
    location = models.CharField(max_length=100)
    nickname = models.CharField(max_length=100)

class Game(models.Model):
    away_team = models.ForeignKey(Team, related_name='away_games')
    away_score = models.PositiveSmallIntegerField(blank=True, null=True)
    home_team = models.ForeignKey(Team, related_name='home_games')
    home_score = models.PositiveSmallIntegerField(blank=True, null=True)
    week = models.PositiveSmallIntegerField(validators=[MaxValueValidator(21)])
    winner = models.ForeignKey(Team, blank=True, null=True)

    def check_winner_played(self):
        if not (winner and (winner.id == away_team.id or winner.id == home_team.id)):
            # raise error("Winner did not compete")

我需要确保获胜者是away_teamhome_team,而不仅仅是任何团队。我创建了check_winner_played方法,但我不知道如何在.save()上调用它。这只会在管理部分,所以我不认为我应该使用表单验证。在我看来,似乎应该在模型级别进行验证。

此外,如果这里有任何东西让你停下来说'这家伙不知道他在做什么'。让我知道。寻找我能得到的任何指针。具体来说,我是否正确验证了week IntegerField最大值?

2 个答案:

答案 0 :(得分:1)

我建议选择另一种方式来确定球队的胜利者, 因为你有多个州但赢了比赛。它也可能是一个相同的分数。

赢得比赛的信息实际上是由球队的得分间接决定的,所以尝试用一个使用得分返回获胜者的属性来模拟获胜的比赛。

class Game(models.Model):
    away_team = models.ForeignKey(Team, related_name='away_games')
    away_score = models.PositiveSmallIntegerField(blank=True, null=True)
    home_team = models.ForeignKey(Team, related_name='home_games')
    home_score = models.PositiveSmallIntegerField(blank=True, null=True)
    week = models.PositiveSmallIntegerField(validators=[MaxValueValidator(21)])

    @property
    def winner():
        if self.away_score > self.home_score:
            return self.away_team
        elif self.away_score < self.home_score:
            return self.home_team
        else:
            return None

这将消除您对其他验证的需求。如果您真的想使用验证器,您应首先阅读有关验证器的django文档:https://docs.djangoproject.com/en/1.11/ref/validators/

答案 1 :(得分:0)

试试这个,它应该引发错误 - 如果获胜者不是空白而且它不是away_team或home_team。 注意它覆盖了save方法,所以这个验证将在Game.save()

上完成
class Team(models.Model):
        abbreviation = models.CharField(max_length=5, unique=True)
        location = models.CharField(max_length=100)
        nickname = models.CharField(max_length=100)

class Game(models.Model):
    away_team = models.ForeignKey(Team, related_name='away_games')
    away_score = models.PositiveSmallIntegerField(blank=True, null=True)
    home_team = models.ForeignKey(Team, related_name='home_games')
    home_score = models.PositiveSmallIntegerField(blank=True, null=True)
    week = models.PositiveSmallIntegerField(validators=[MaxValueValidator(21)])
    winner = models.ForeignKey(Team, blank=True, null=True)

    def save(self, *args, **kwargs):
        if not (self.winner and (self.winner == self.away_team or self.winner == self.home_team)):
              raise ValidationError('Winner Error')
        super(Post, self).save(*args, **kwargs)

由于您正在使用ValidationError,因此需要在models.py(顶部)中导入ValidationError:

from django.core.exceptions import ValidationError