我有这个参赛模特:
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'
有人可以告诉我我在这里做错了什么吗?
看起来像是丢失/未应用的迁移问题。
无论哪种方式,任何试图给你理由的答案对你都没有帮助。
这是你应该做的:
还有很多其他的事情你可以在这里改进,但在这个阶段对你没有帮助,但单元测试无疑是第一步。
添加缺少迁移的测试(有很多在线链接)。
添加单元测试后: