【问题标题】:Catching DoesNotExist exception in a custom manager in Django在 Django 的自定义管理器中捕获 DoesNotExist 异常
【发布时间】:2012-12-24 16:12:25
【问题描述】:

我有一个 Django 模型的自定义管理器。我似乎无法在这里捕捉到 DoesNotExist 异常。我知道如何在模型中执行此操作,但在这里不起作用:

class TaskManager(models.Manager):
    def task_depend_tree(self, *args, **kwargs):
        if "id" in kwargs:
            try:
                task = self.get(id=kwargs["id"])
            except DoesNotExist:
                raise Http404

Get_object_or_404 也不起作用。 这里有什么问题?

【问题讨论】:

  • 对于这两种情况,“不起作用”是什么意思?实际发生了什么?
  • @DanielRoseman NameError: 未定义全局名称“DoesNotExist”

标签: python django exception django-custom-manager


【解决方案1】:

在 Django 中,模型中的每个对象都有一个异常属性 DoesNotExists。因此,您可以从对象本身或异常模块中调用它。

来自对象 (self):

from django.db import models

class TaskManager(models.Manager):
    def task_depend_tree(self, *args, **kwargs):
        if "id" in kwargs:
            try:
                task = self.get(id=kwargs["id"])
            except self.model.DoesNotExist:
                raise Http404

来自异常模块:

from django.core.exceptions import ObjectDoesNotExist

try:
    return "Calling object"
except ObjectDoesNotExist:
    raise Http404

【讨论】:

    【解决方案2】:

    我以这种方式处理异常并且它起作用了。

    from django.core.exceptions import ObjectDoesNotExist
    
    try:
        task = self.get(id=kwargs["id"])
    except ObjectDoesNotExist as DoesNotExist:
        raise Http404
    
    

    【讨论】:

    • DoesNotExist 这个名字在这里很容易误导,根本没有使用
    【解决方案3】:

    您可以使用 Manager.model (self.model) 实例中的 DoesNotExist, 当您说 objects = MyManager() 时,您是在 MyManager 类中分配 self.model。

            try:
                task = self.get(id=kwargs["id"])
                return task
            except self.DoesNotExist:
                return None
    

    【讨论】:

    • 这行不通。你必须使用 self.model.DoesNotExist
    【解决方案4】:

    如果您需要使用 GenericViewSet 在列表方法 (DRF) 上实现此功能,并且需要返回一个空列表,请使用:

        def list(self, request, *args, **kwargs):
        self.get_object() # I use this to trigger the object_permission
        try:
            queryset = self.queryset.filter(user=(YourModel.objects.get(user=request.user).user))
        except YourModel.DoesNotExist:
            return Response(YourModel.objects.none())
    
        serializer = YSourModelSerializer(queryset, many=True)
        return Response(serializer.data)
    

    【讨论】:

    • 这是处理此异常最简洁的方法,因为它不涉及导入异常
    【解决方案5】:

    正如 panchicore 建议的那样,self.model 是正确的选择。

    class TaskManager(models.Manager):
        def task_depend_tree(self, *args, **kwargs):
            if "id" in kwargs:
                try:
                    task = self.get(id=kwargs["id"])
                except self.model.DoesNotExist:
                    raise Http404
    

    【讨论】:

      【解决方案6】:

      尝试使用ObjectDoesNotExist 代替DoesNotExist 或可能使用self.DoesNotExist。如果一切都失败了,试着抓住一个香草Exception 并评估它以查看它的 type()。

      from django.core.exceptions import ObjectDoesNotExist

      【讨论】:

      • 我试过 Self.DoesNotExist 但失败了。当数据库中不存在某些东西时我得到的错误是:NameError: global name 'DoesNotExist' is not defined 所以我需要从某个地方导入DoesNotExist。我以为它在 models.Model 中,但 models.Model.DoesNotExist 不起作用。
      • self.DoesNotExist 显然不会有帮助,因为如果 self 有这样的方法,它就存在。请改用task.DoesNotExistObjectDoesNotExist
      • 您尝试过我的ObjectDoesNotExist 建议了吗?其他语法可能是 self.model.DoesNotExist... 但我不确定。
      • 我必须导入 ObjectDoesNotExist 并且它成功捕获了 DoesNotExist:from django.db.models.base import ObjectDoesNotExist 谢谢!
      猜你喜欢
      • 2014-12-20
      • 2015-06-07
      • 1970-01-01
      • 2018-05-30
      • 1970-01-01
      • 1970-01-01
      • 2017-05-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多