1

I have two foreign key fields that point to the same model. I would like to prevent them from having the same value. Here is my code that does not work

class Match(models.Model):
    team_a = models.ForeignKey(Team, related_name='team_a', on_delete=models.CASCADE)
    team_b = models.ForeignKey(Team, related_name='team_b', on_delete=models.CASCADE)
    match_date_time = models.DateTimeField(validators=[validate_matchdate])
    winner = models.CharField(choices=CHOICES, max_length=50, blank=True, null=True)
    
    
    def clean(self):
        direct = Match.objects.filter(team_a = self.team_a, team_b=self.team_b)
        reverse = Match.objects.filter(team_a = self.team_b, team_b=self.team_a)
        
        if direct.exists() & reverse.exists():
            raise ValidationError('A team cannot be against itself')
sajeyks mwangi
  • 549
  • 8
  • 20

1 Answers1

1

You can add a CheckConstraint [Django-doc] such that the database will enforce this:

from django.db.models import F, Q


class Match(models.Model):
    team_a = models.ForeignKey(
        Team, related_name='matches_as_a', on_delete=models.CASCADE
    )
    team_b = models.ForeignKey(
        Team, related_name='matches_as_b', on_delete=models.CASCADE
    )
    match_date_time = models.DateTimeField(validators=[validate_matchdate])
    winner = models.CharField(
        choices=CHOICES, max_length=50, blank=True, null=True
    )

    class Meta:
        constraints = [
            models.CheckConstraint(
                check=~Q(team_a=F('team_b')), name='not_play_against_itself'
            )
        ]
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555