尽管使用了 if 语句,但 RelatedObjectDoesNotExist 错误

Posted

技术标签:

【中文标题】尽管使用了 if 语句,但 RelatedObjectDoesNotExist 错误【英文标题】:RelatedObjectDoesNotExist error inspite of using if statement 【发布时间】:2019-02-07 10:27:06 【问题描述】:

我有下面的代码if self.request.user.is_authenticated() and self.request.user. userlocation 我不明白为什么我得到这个用户没有用户定位错误。如果不满足他的条件,我有一个 if 语句,它不应该只是向下显示上下文

class Homepage(TemplateView):
    template_name = 'home.html'

    def get_context_data(self, **kwargs):
        context = super(Homepage, self).get_context_data(**kwargs)
        context['event_list'] = Event.objects.all()
        if self.request.user.is_authenticated() and self.request.user.userlocation:
            print("The code reached here ")
        return context

下面是models.py

class UserLocation(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    lat = models.FloatField(blank=True, null=True)
    lon = models.FloatField(blank=True, null=True)
    point = models.PointField(srid=4326, default='SRID=4326;POINT(0.0 0.0)')
    objects = models.GeoManager()

【问题讨论】:

这是来自UserLocationOneToOneField吗? @WillemVanOnsem 是的 OneToOneField 我已经在问题中添加了模型 @WillemVanOnsem 你能在上面的问题中检查我对你的代码的实现吗我做错了什么我仍然遇到同样的错误 import ObjectDoesNotExists 出错了吗? @WillemVanOnsem 是的 from django.core.exceptions import ObjectDoesNotExist 我正在使用 pycharm 专业版,它向我显示了这些错误 【参考方案1】:

我猜你构建的模型看起来类似于:

class UserLocation(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    # ...

与普遍看法相反,一对一字段意味着引用的模型(此处为User总是有一个UserLocation 对象。 OneToOneField 实际上是一个带有unique=True 约束的ForeignKey 字段(以及一些额外的逻辑,例如反向关系不是userlocation_set,而是userlocation)。所以这意味着两个UserLocations 不能永远引用相同User对象。

因此,某些user 可能没有user.userlocation,如果调用该属性,不幸的是它返回not None,但会引发错误(有请求它返回None,但由于向后兼容性,它可能不会在(不久的)将来实现)。

所以你应该检查try-catch-except:

from django.core.exceptions import ObjectDoesNotExist

class Homepage(TemplateView):
    template_name = 'home.html'

    def get_context_data(self, **kwargs):
        context = super(Homepage, self).get_context_data(**kwargs)
        context['event_list'] = Event.objects.all()
        if self.request.user.is_authenticated()
            try:
                my_location = self.request.user.userlocation
            except ObjectDoesNotExist:
                # ... hande case where the location does not exists
            else:
                print("The location is ".format(my_location))
        return context

【讨论】:

except user.userlocation.DoesNotExist: 可能会更具体一点:) @JPG:是ObjectDoesNotExists,这是所有DoesNotExists模型中的“母班”。见:docs.djangoproject.com/en/2.1/ref/exceptions/… 通过写user.userlocation.DoesNotExist:,问题将不会得到解决,因为现在它会在except 子句部分引发user.userlocation 的异常:)跨度> 最后一条评论太棒了:+1【参考方案2】:

在您的 if 子句中使用一个额外条件,该条件使用 Python 的 hasattr() 检查是否存在 userlocation 属性方法

试试这个

class Homepage(TemplateView):
    template_name = 'home.html'

    def get_context_data(self, **kwargs):
        context = super(Homepage, self).get_context_data(**kwargs)
        context['event_list'] = Event.objects.all()
        if self.request.user.is_authenticated() and \
                hasattr(self.request.user, 'userlocation') and \
                self.request.user.userlocation:
            print("The code reached here ")
        return context

参考Django check if a related object exists error: RelatedObjectDoesNotExist

【讨论】:

这也很有效,再次感谢 hasattr() 我实际上编写了您的解决方案,这两个解决方案都很棒。我也对你的答案投了赞成票。感谢您的详细参考 @Willem Van Onsem 总是喜欢写描述性的答案,我有点懒;) 并且使用try...catch 块是处理异常的更pythonic方式(比条件表达式)【参考方案3】:

User 类没有 userlocation 变量。 使用继承自User的自定义用户类

【讨论】:

如果那样的话,它会上升一个AttributeError。该关系是OneToOneFieldreverse 的结果。

以上是关于尽管使用了 if 语句,但 RelatedObjectDoesNotExist 错误的主要内容,如果未能解决你的问题,请参考以下文章

PHP嵌入式IF语句约定

尽管编辑了我的包含语句以修复,但得到“错误 C2653:'TextureManager':不是类或命名空间名称”

Oracle PL/SQL 动态 if 语句全局变量

尽管 if (应该充当过滤器),但所有元素都推入数组

尽管函数定义中有 RETURN 语句,但 Postgres 查询没有结果数据的目的地

SAS条件IF-THEN语句不起作用