Django:“;ZeroToOneField“;DoesNotExist错误

Django:“;ZeroToOneField“;DoesNotExist错误,django,model,one-to-one,Django,Model,One To One,我试图确定在两个模型之间建立“零对一”关系的最佳方法。例如,名为Post的模型可以有零个或一个名为PostExtra的模型的相关模型实例。我希望反过来也是正确的 from django.db import models class PostExtra(models.Model): author = models.CharField(max_length=64) active = models.BooleanField(default=False) """

我试图确定在两个模型之间建立“零对一”关系的最佳方法。例如,名为Post的模型可以有零个或一个名为PostExtra的模型的相关模型实例。我希望反过来也是正确的

from django.db import models

class PostExtra(models.Model):

    author = models.CharField(max_length=64)
    active = models.BooleanField(default=False)  

    """
    Assigned a property to prevent DoesNotExist error when calling 
    self.post, but property does not override self.post properly 
    for some reason. 
    """ 
    def _get_post(self):
        return_value=None
        try:
            return_value = self.post
        except:
            pass
        return return_value

    def _set_post(self, post):
        self.post = post

    post = property(_get_post, _set_post)

    def __unicode__(self):
        return "%s" % (self.author)

class Post(models.Model):

    title = models.CharField(max_length=64)
    text = models.TextField()
    extra = models.OneToOneField('a.PostExtra', blank=True, null=True)

    def __unicode__(self):
        return "%s" % (self.title)
在这里,我可以创建一个Post()

如上所述,由于我使用blank=True/null=True将Post.extra设为OneToOneField,因此如果没有分配PostExtra,p.extra将返回null。然而,如果我做相反的操作并尝试访问PostExtra.post,我会得到一个DoesNotExist错误

>>> pe = PostExtra(author='John Doe')
>>> pe.save()
>>> pe.post 
...
DoesNotExist: Post matching query does not exist.
我尝试在PostExtra上指定一个属性,以使用属性覆盖PostExtra.post,但仍然出现错误。有没有人找到方法让OneToOneFields在尝试访问不存在的相关元素时不抛出异常(并返回Null)


任何建议都将不胜感激

为了使这种类型的代码正常工作,您需要指定不同的代码

from django.core.exceptions import ObjectDoesNotExist
class PostExtra(models.Model):
    pass ## Brevity.
    def _get_post(self):
        return_value=None
        try:
            return_value = self._post
        except ObjectDoesNotExist: ## Be explicit if you can.
            pass
        return return_value
    def _set_post(self, post):
        self._post = post
    post = property(_get_post, _set_post)

class Post(models.Model):
    pass ## Brevity.
    extra = models.OneToOneField('a.PostExtra', blank=True,
                      null=True, related_name='_post')
然后,您可以通过几种不同的方式访问帖子:

>>> pe = PostExtra(author='John Doe')
>>> pe.save()
>>> pe.post
None
>>> pe._post
DoesNotExist: Post matching query does not exist.
忍者编辑:

有人可能会问:“我为什么要这样做?”。答案是因为当Django模型类设置
PostExtra
对象时,它正在创建
PostExtra.post
作为对
post
的引用。我不熟悉代码本身,但我怀疑它会在执行任务之前检查以确保海岸线清晰,因为程序员让它建立这种关系。因此,您必须为Django的模型类指定一个不冲突的属性,从而使用
相关的\u name
参数。

您的try/except没有捕捉到错误,或者是您后来添加的内容?从
\u get\u post()
内部调用
self.post
似乎无论如何都会递归。谢谢Jack M。因为这样做“except:”本身会捕获任何异常,它不也应该捕获DoesNotExist异常吗?更重要的是,如果代码正常工作,你会一次又一次地以
PostExtra.post
(它被重定向到
\u get\u post()
)的形式重复它,称为
PostExtra.post
,它会调用
PostExtra.post
,等等,直到Python把你全新的鞋子都吐出来。再次感谢。这似乎可以将相关名称隐藏为私有变量,至少有助于防止调用它。
>>> pe = PostExtra(author='John Doe')
>>> pe.save()
>>> pe.post
None
>>> pe._post
DoesNotExist: Post matching query does not exist.