gpt4 book ai didi

python - Django - 验证 m2m 关系

转载 作者:行者123 更新时间:2023-12-05 05:31:41 24 4
gpt4 key购买 nike

我有以下模型:

class Question(Model):
# ...

class Choice(Model):
question = ForeignKey(Question)
# ...

class AnswerToQuestion(Model):
user = ForeignKey(User)
question = ForeignKey(Question)
selected_choices = ManyToManyField(Choice)

我想做的是确保 selected_choices 中的值始终是属于存储在 question 字段中的问题的选项。

这是我在 AnswerToQuestionclean 方法中尝试的:

    def clean(self):
super().clean()
if self.pk and self.selected_choices.exclude(question=self.question).exists():
raise ValidationError("Invalid choice(s)")

然而,这并不像预期的那样工作:因为 m2m 关系在实际模型保存后更新,如果我尝试关联一个无效的选择,这将工作正常,然后每次后续保存都会失败,因为我 已经有一个无效的关联选择。

还有其他方法可以实现我想要做的事情吗?

最佳答案

另一种方法可能是使用 through-model .

假设你有这样的:

class Choice(Model):
question = ForeignKey(Question)
# ...

class AnswerToQuestion(Model):
user = ForeignKey(User)
question = ForeignKey(Question)
selected_choices = ManyToManyField(Choice, through="AnswerToQuestionChoiceM2M", through_fields=("answer", "choice"))


class AnswerToQuestionChoiceM2M(Model):
answer = ForeignKey(AnswerToQuestion)
choice = ForeignKey(Choice)
# ...

然后就可以直接保存关系了:

AnswerToQuestionChoiceM2M(answer_id=..., choice_id=...).save()

如果关系存在,数据库会告诉你,所以你会捕获异常:

try:
AnswerToQuestionChoiceM2M(answer_id=..., choice_id=...).save()
except IntegrityError:
raise ValidationError("Invalid choice(s)")

这种方法是并发友好的,因为实际的验证发生在数据库内部。数据库擅长处理并发事务,因此您不必这样做。

这种方法还允许您添加更多信息AnswerToQuestionChoiceM2M,以备不时之需。例如,您可能希望在选择发生时保护 datetime

此方法确实需要更多代码。此外,如果您不习惯,直接处理 M2M 关系可能会感觉很奇怪。

关于python - Django - 验证 m2m 关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74314407/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com