django http404 详解

Posted jiangle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django http404 详解相关的知识,希望对你有一定的参考价值。

【引子】

  今天在看django的官方文档的时候看到get_object_or_404这个函数感觉比较奇怪。这个主要来自于它的功能,如果要查询的对象

  存在那么就返回对象;如果对象不存在那么就要报404 Not Found ;但是404 Not Found并不是它的返回值,而django直接返回

  了404页面、这个感觉就比较奇怪了。

 

1、对get_object_or_404的一次失败地模拟

from django.shortcuts import render
from django.http import Http404,HttpResponse


def fun_get_object_or_404(pk=None):
    if pk == 1:
        return 1
    else:
        return HttpResponse(object is not found ...)



def index(request):
    obj = fun_get_object_or_404()
    return HttpResponse("object is {0}".format(obj))

先看一下view的执行结果吧

技术分享图片

从返回的内容我们可以看出来、view对HttpResponse的处理并不像middleware中的那样;middleware只要是遇到return HttpResponse 这样的

内容就会马上返回response对象到浏览器;那get_object_or_404 是怎么实现的呢?

 

2、get_object_or_404 的官方实现

def get_object_or_404(klass, *args, **kwargs):
    """
    Use get() to return an object, or raise a Http404 exception if the object
    does not exist.

    klass may be a Model, Manager, or QuerySet object. All other passed
    arguments and keyword arguments are used in the get() query.

    Like with QuerySet.get(), MultipleObjectsReturned is raised if more than
    one object is found.
    """
    queryset = _get_queryset(klass)
    try:
        return queryset.get(*args, **kwargs)
    except AttributeError:
        klass__name = klass.__name__ if isinstance(klass, type) else klass.__class__.__name__
        raise ValueError(
            "First argument to get_object_or_404() must be a Model, Manager, "
            "or QuerySet, not ‘%s‘." % klass__name
        )
    except queryset.model.DoesNotExist:
        raise Http404(No %s matches the given query. % queryset.model._meta.object_name)

这个也只是raise 了一个Http404、注意这里是raise 而不是return 说明Http404并不是一个HttpResponse的子类、应该是一个异常。

 

3、Http404的官方实现

class Http404(Exception):
    pass

扎心啦! 这货就一个简单的Exception 子类、并不是HttpResponse的子类、还有一点要注意的不要想用raise Exception(‘xxx‘)的方式来

替代Http404是行不通的、这样做话会直接报错。

 

 

----

以上是关于django http404 详解的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Django 的自定义 404 错误模板中显示传递给 Http404 的消息?

Django REST 框架 http 404 详细信息”:“未找到。”

Django:找不到页面(404)

如何捕获 Django HTTP 异常?

Django - 为开发 Web 服务器显示 404 页面 (http://127.0.0.1:8000/)

(已解决):-)(React 和 Django)我无法从我的用户列表中删除用户。 (HTTP 状态码 404)