简体   繁体   中英

Django - How to restrict Foreign Key choices to a ManyToMany field in another model

I have 3 models: Championship , Team and Match . Championship and Team are related with a ManyToManyField because each team can participate in multiple championships and each championship has many teams. And each match should be linked to a championship but also to 2 teams that are in the championship.

class Championship(models.Model):
    name = models.CharField(max_length=100)
    teams = models.ManyToManyField(Team)

class Team(models.Model):
    name = models.CharField(max_length=100)

class Match(models.Model):
    championship = models.ForeignKey(Championship)
    team1 = models.ForeignKey(Team)
    team2 = models.ForeignKey(Team)
    score1 = models.PositiveIntegerField()
    score2 = models.PositiveIntegerField()

I would like to ensure that 'team1' and 'team2' are in 'championship'. And also that 'team1' and 'team2' are different.

How could I do that ?

Maybe i could use something like Django-smart-selects but i would prefer to avoid using a third-party app.

You can do model validation in the save method:

from django.core.exceptions import ValidationError


class Match(models.Model):
    championship = models.ForeignKey(Championship)

    team1 = models.ForeignKey(Team)
    team2 = models.ForeignKey(Team)

    score1 = models.PositiveIntegerField()
    score2 = models.PositiveIntegerField()

    def save(self, *args, **kwargs):
        if self.team1 == self.team2:
            raise ValidationError('The two teams in a match must be distinct')

        all_teams = self.championship.teams.all()

        if self.team1 not in all_teams or self.team2 not in all_teams:
            raise ValidationError('Both teams must be in the championship')

        return super(Match, self).save(*args, **kwargs)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM