为什么我无法深入模型以到达字段?

问题描述 投票:0回答:1

我有这个参赛模特:

class Contestant(models.Model):
    GENDERS = [
        ("male", "Male"),
        ("female", "Female")
    ]
    EYE_COLORS = [
        ("brown", "Brown"),
        ("blue", "Blue"),
        ("green", "Green"),
        ("hazel", "Hazel"),
        ("amber", "Amber"),
        ("gray", "Gray")
    ]
    HAIR_COLORS = [
        ("black", "Black"),
        ("brown", "Brown"),
        ("blonde", "Blonde"),
        ("red", "Red"),
        ("gray", "Gray"),
        ("white", "White"),
        ("pink", "Pink"),
        ("purple", "Purple"),
        ("green", "Green"),
        ("orange", "Orange")
    ]
    main_photo = models.FileField(upload_to='main_image/')
    first_name = models.CharField(max_length=50)
    middle_name = models.CharField(max_length=50, null=True, blank=True)
    last_name = models.CharField(max_length=50)
    date_of_birth = models.DateField()
    gender = models.CharField(max_length=8, choices=GENDERS)
    height = models.IntegerField(default=0,validators=[MinValueValidator(0), MaxValueValidator(120)])
    weight = models.IntegerField(default=0,validators=[MinValueValidator(0), MaxValueValidator(1500)])
    eye_color = models.CharField(max_length=20, choices=EYE_COLORS)
    hair_color = models.CharField(max_length=20, choices=HAIR_COLORS)
    city = models.OneToOneField(City, on_delete=models.DO_NOTHING, related_name="contestant")
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="contestant_profile")

    created_at = models.DateTimeField(auto_now_add=True, verbose_name="created at")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="updated at")

    class Meta:
        verbose_name = "contestant"
        verbose_name_plural = "contestants"
        db_table = "contestants"

    def __str__(self):
        return f"contestant {self.user}"

我希望人们为参赛者投票。这是投票模型:

class ContestantVote(models.Model):
    contestant = models.ForeignKey(Contestant, on_delete=models.CASCADE)
    score = models.IntegerField(default=0, validators=[MinValueValidator(0), MaxValueValidator(10)])
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="votes")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="created at")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="updated at")

    class Meta:
        unique_together = (("contestant", "user"),)
        verbose_name = "vote"
        verbose_name_plural = "votes"
        db_table = "votes"

    def save(self, *args, **kwargs):
        if ContestantVote.objects.filter(contestant=self.contestant, user=self.user).exists():
            raise ValidationError(f'User {self.user} has already voted for contestant {self.contestant}.')

        if self.score == 10:
            existing_vote = ContestantVote.objects.filter(
                user=self.user,
                contestant__gender=self.contestant.gender,
                score=10
            ).exists()
            if existing_vote:
                raise ValidationError(f'User {self.user} has already given a score of 10 to a {self.contestant.gender} contestant.')
        
        super().save(*args, **kwargs)

    def __str__(self):
        return f"Vote for {self.contestant} by {self.user}"

我试图阻止用户给同性别的两名参赛者相同的最高分,即 10,但我不断遇到同样的错误,投票中不存在该字段,但我正在尝试检查该字段在相关字段上使用双下划线格式。

这是错误:

django.core.exceptions.FieldDoesNotExist: ContestantVote has no field named 'contestant__gender'

有人可以告诉我我在这里做错了什么吗?

python django
1个回答
0
投票

看起来像是丢失/未应用的迁移问题。

无论哪种方式,任何试图给你理由的答案对你都没有帮助。

这是你应该做的:

  1. 创建单元测试
  2. 创建单元测试
  3. 创建单元测试

还有很多其他的事情你可以在这里改进,但在这个阶段对你没有帮助,但单元测试无疑是第一步。

添加缺少迁移的测试(有很多在线链接)。

添加单元测试后:

  1. 返回测试通过的代码
  2. 添加一些你想要的代码
  3. 测试直到通过
  4. 返回步骤 2。
© www.soinside.com 2019 - 2024. All rights reserved.