Django:OneToOneField - RelatedObjectDoesNotExist
Django : OneToOneField - RelatedObjectDoesNotExist
我的模型中有以下两个 类:
class Answer(models.Model):
answer = models.CharField(max_length=300)
question = models.ForeignKey('Question', on_delete=models.CASCADE)
def __str__(self):
return "{0}, view: {1}".format(self.answer, self.answer_number)
class Vote(models.Model):
answer = models.OneToOneField(Answer, related_name="votes", on_delete=models.CASCADE)
users = models.ManyToManyField(User)
def __str__(self):
return str(self.answer.answer)[:30]
在shell我取第一个答案:
>>> Answer.objects.all()[0]
<Answer: choix 1 , view: 0>
我要获取投票对象:
>>> Answer.objects.all()[0].votes
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Users\Hippolyte\AppData\Roaming\Python\Python38\site-packages\django\db\models\fields\related_descriptors.py", line 420, in __get__
raise self.RelatedObjectDoesNotExist(
questions.models.Answer.votes.RelatedObjectDoesNotExist: Answer has no votes.
但是出现错误。
我不明白为什么 related_name
不被识别。你能帮帮我吗?
您在这里使用了 OneToOneField
。因此,这意味着每个 Vote
指向一个 不同的 Anwer
对象。因此,每个 Answer
最多 个 Vote
。像 some_answer.votes
这样的查询将立即查询那个 Vote
对象,如果它不存在,它将引发 RelatedObjectDoesNotExist
错误(这是 ObjectDoesNotExist
异常的子类).所以 related_name
本身被识别了,但是没有相关的 Vote
对象。
然而在这里使用 OneToOneField
是令人惊讶的。意思是每次投票都指向一个唯一的Answer
?我想你可能想在这里使用 ForeignKey
,否则 related_name='votes'
没有多大意义。
通过不使用 OneToOne 关系查询 Vote
模型来检查您的 Answer
是否有 Vote
尝试做:
ans = Answer.objects.all()[0]
Vote.objects.filter(answer_id = ans.id).all()
额外提示,你应该在related_name上使用单数词(vote
而不是votes
),因为它是OneToOne,意味着一个Answer只能一个Vote(反之亦然)
您的 related_name
已被识别,但仅当相关对象存在时才分配给实例。
在您的情况下,您的数据库中没有 Vote
实例,其 answer
字段指向您的 Answer
实例
只要捕获异常,return None
如果你想继续:
answer = Answer.objects.all().first()
try:
vote = answer.votes
except Answer._meta.model.related_field.RelatedObjectDoesNotExist as e:
vote = None
如果你想缩短它,你可以使用 hasattr(answer, 'vote')
来检查,但这将掩盖所有由数据库查找引起的异常
answer = Answer.objects.all().first()
vote = answer.votes if hasattr(answer, 'votes') else None
请注意,由于您使用了 OneToOneField,如果相关 Vote
存在,answer.votes
将始终 return 单个实例。因此,使用 related_name='vote'
(没有 s)
会更合适
我的模型中有以下两个 类:
class Answer(models.Model):
answer = models.CharField(max_length=300)
question = models.ForeignKey('Question', on_delete=models.CASCADE)
def __str__(self):
return "{0}, view: {1}".format(self.answer, self.answer_number)
class Vote(models.Model):
answer = models.OneToOneField(Answer, related_name="votes", on_delete=models.CASCADE)
users = models.ManyToManyField(User)
def __str__(self):
return str(self.answer.answer)[:30]
在shell我取第一个答案:
>>> Answer.objects.all()[0]
<Answer: choix 1 , view: 0>
我要获取投票对象:
>>> Answer.objects.all()[0].votes
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Users\Hippolyte\AppData\Roaming\Python\Python38\site-packages\django\db\models\fields\related_descriptors.py", line 420, in __get__
raise self.RelatedObjectDoesNotExist(
questions.models.Answer.votes.RelatedObjectDoesNotExist: Answer has no votes.
但是出现错误。
我不明白为什么 related_name
不被识别。你能帮帮我吗?
您在这里使用了 OneToOneField
。因此,这意味着每个 Vote
指向一个 不同的 Anwer
对象。因此,每个 Answer
最多 个 Vote
。像 some_answer.votes
这样的查询将立即查询那个 Vote
对象,如果它不存在,它将引发 RelatedObjectDoesNotExist
错误(这是 ObjectDoesNotExist
异常的子类).所以 related_name
本身被识别了,但是没有相关的 Vote
对象。
然而在这里使用 OneToOneField
是令人惊讶的。意思是每次投票都指向一个唯一的Answer
?我想你可能想在这里使用 ForeignKey
,否则 related_name='votes'
没有多大意义。
通过不使用 OneToOne 关系查询 Vote
模型来检查您的 Answer
是否有 Vote
尝试做:
ans = Answer.objects.all()[0]
Vote.objects.filter(answer_id = ans.id).all()
额外提示,你应该在related_name上使用单数词(vote
而不是votes
),因为它是OneToOne,意味着一个Answer只能一个Vote(反之亦然)
您的 related_name
已被识别,但仅当相关对象存在时才分配给实例。
在您的情况下,您的数据库中没有 Vote
实例,其 answer
字段指向您的 Answer
实例
只要捕获异常,return None
如果你想继续:
answer = Answer.objects.all().first()
try:
vote = answer.votes
except Answer._meta.model.related_field.RelatedObjectDoesNotExist as e:
vote = None
如果你想缩短它,你可以使用 hasattr(answer, 'vote')
来检查,但这将掩盖所有由数据库查找引起的异常
answer = Answer.objects.all().first()
vote = answer.votes if hasattr(answer, 'votes') else None
请注意,由于您使用了 OneToOneField,如果相关 Vote
存在,answer.votes
将始终 return 单个实例。因此,使用 related_name='vote'
(没有 s)