Django视图函数及快捷方式

一、简单地视图

    下面是一个返回当前日期和时间作为HTML文档的视图:

from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

    来分析一下上面的代码:

      ·首先,从django.http模块导入了HttpResponse类。

      ·接着,我们定义了current_datetime视图函数。

      ·每个视图函数都接收一个HttpRequest对象作为第一位置参数,一般取名为request,你可以取别的名字,但这不符合潜规则,最好不要那么做。

      ·视图函数的名称没有强制规则,但尽量不要和Python及Django内置的各种名称重名,并且尽量精确地反映出它的功能,比如这里的current_datetime

      ·该视图返回一个HttpResponse对象,其中包含生成的HTML页面。

二、返回错误

    在Django中返回HTTP错误代码是非常简单的。

    HttpResponse的许多子类对应着除了200(代表“OK”)以外的一些常用的HTTP状态码。

    为了标示一个错误,可以直接返回那些子类中的一个实例,而不是普通的HttpResponse。像下面这样:

from django.http import HttpResponse, HttpResponseNotFound

def my_view(request):
    # ...
    if foo:
        return HttpResponseNotFound('<h1>Page not found</h1>')
    else:
        return HttpResponse('<h1>Page was found</h1>')

    Django为404错误提供了一个特化的子类HttpResponseNotFound。由于一些状态码不太常用,所以不是每个状态码都有一个特化的子类。

    也可以向HttpResponse的构造器传递HTTP状态码,来创建你想要的任何状态码的返回类。 像下面这样:

from django.http import HttpResponse

def my_view(request):
    # ...

    # Return a "created" (201) response code.
    return HttpResponse(status=201)

    关键是在返回中提供status=201参数。别的什么303之类的错误都可以参照上面的例子。

三、Http404异常

    class django.http.Http404。这是一个Django内置的异常类。可以在需要的地方人为弹出它,Django会捕获它,并且带上HTTP404错误码返回你当前app的标准错误页面或者自定义错误页面。像下面这样:

from django.http import Http404
from django.shortcuts import render
from polls.models import Poll

def detail(request, poll_id):
    try:
        p = Poll.objects.get(pk=poll_id)
    except Poll.DoesNotExist:
        raise Http404("Poll does not exist")
    return render(request, 'polls/detail.html', {'poll': p})

    为了在Django返回404时显示自定义的HTML,可以创建一个名为404.html的HTML模板,并将其放置在模板树的顶层。 当DEBUG设置为False时,此模板将被自动使用。当DEBUG为True时,可以向Http404提供消息,它将显示在标准的内置404调试模板中,可以使用这些消息进行调试。

四、Django内置的快捷方式

    Django在django.shortcuts模块中,为我们提供了很多快捷方便的类和方法,它们都很重要,使用频率很高。

   1、render()

    render(request, template_name, context=None, content_type=None, status=None, using=None)[source]

    结合一个给定的模板和一个给定的上下文字典,返回一个渲染后的HttpResponse对象。

    必需参数:

      ·request:视图函数处理的当前请求,封装了请求头的所有数据,其实就是视图参数request。

      ·template_name:要使用的模板的完整名称或者模板名称的列表。如果是一个列表,将使用其中能够查找到的第一个模板。

    可选参数:

      ·context:添加到模板上下文的一个数据字典。默认是一个空字典。可以将认可需要提供给模板的数据以字典的格式添加进去。这里有个小技巧,使用Python内置的locals()方法,可以方便的将函数作用于内的所有变量一次性添加。

      ·content_type:用于生成的文档的MIME类型。 默认为DEFAULT_CONTENT_TYPE设置的值。

      ·status:响应的状态代码。 默认为200。

      ·using:用于加载模板使用的模板引擎的NAME。

    范例:

    下面的例子将渲染模板myapp/index.html,MIME类型为application/xhtml+xml

from django.shortcuts import render

def my_view(request):
    # View code here...
    return render(request, 'myapp/index.html', {
        'foo': 'bar',
    }, content_type='application/xhtml+xml')

    这个示例等同于:

from django.http import HttpResponse
from django.template import loader

def my_view(request):
    # View code here...
    t = loader.get_template('myapp/index.html')
    c = {'foo': 'bar'}
    return HttpResponse(t.render(c, request), content_type='application/xhtml+xml')

   2、render_to_response()

    render_to_response(template_name, context=None, content_type=None, status=None, using=None)[source]

    此功能在引入render()之前进行,不推荐,以后可能会被弃用。

   3、redirect()

    redirect(to, permanent=False, args, *kwargs)[source]

    根据传递进来的url参数,返回HttpResponseRedirect。

    参数to可以是:

      ·一个模型:将调用模型的get_absolute_url()函数,反向解析出目的url;

      ·视图名称:可能带有参数:reverse()将用于反向解析url;

      ·一个绝对的或相对的URL:将原封不动的作为重定向的目标位置。

    默认情况下是临时重定向,如果设置permanent=True将永久重定向。

    范例:

    1.调用对象的get_absolute_url()方法来重定向URL:

from django.shortcuts import redirect

def my_view(request):
    ...
    object = MyModel.objects.get(...)
    return redirect(object)

    2.传递视图名,使用reverse()方法反向解析url:

def my_view(request):
    ...
    return redirect('some-view-name', foo='bar')

    3.重定向到硬编码的URL:

def my_view(request):
    ...
    return redirect('/some/url/')

    4.重定向到一个完整的URL:

def my_view(request):
    ...
    return redirect('https://example.com/')

    所有上述形式都接受permanent参数;如果设置为True,将返回永久重定向:

def my_view(request):
    ...
    object = MyModel.objects.get(...)
    return redirect(object, permanent=True)

   4、get_object_or_404()

    get_object_or_404(klass, args, *kwargs)[source]

    这个方法,非常有用,请一定熟记。常用于查询某个对象,找到了则进行下一步处理,如果未找到则给用户返回404页面。

    在后台,Django其实是调用了模型管理器的get()方法,只会返回一个对象。不同的是,如果get()发生异常,会引发Http404异常,从而返回404页面,而不是模型的DoesNotExist异常。

    必需参数:

      ·klass:要获取的对象的Model类名或者Queryset等;

      ·**kwargs:查询的参数,格式应该可以被get()接受。

    范例:

    1.从MyModel中使用主键来获取对象:

from django.shortcuts import get_object_or_404

def my_view(request):
    my_object = get_object_or_404(MyModel, pk=1)

    这个示例等同于:

from django.http import Http404

def my_view(request):
    try:
        my_object = MyModel.objects.get(pk=1)
    except MyModel.DoesNotExist:
        raise Http404("No MyModel matches the given query.")

    2.除了传递Model名称,还可以传递一个QuerySet实例:

queryset = Book.objects.filter(title__startswith='M')
get_object_or_404(queryset, pk=1)

    上面的示例不够简洁,因为它等同于:

get_object_or_404(Book, title__startswith='M', pk=1)

    但是如果你的queryset来自其它地方,它就会很有用了。

    3.还可以使用Manager。 如果你自定义了管理器,这将很有用:

get_object_or_404(Book.dahl_objects, title='Matilda')

    4.还可以使用related managers:

author = Author.objects.get(name='Roald Dahl')
get_object_or_404(author.book_set, title='Matilda')

    与get()一样,如果找到多个对象将引发一个MultipleObjectsReturned异常。

   5、get_list_or_404()

    get_list_or_404(klass, args, *kwargs)[source]

    这其实就是get_object_or_404多值获取版本。在后台,返回一个给定模型管理器上filter()的结果,并将结果映射为一个列表,如果结果为空则弹出Http404异常。

    必需参数:

      ·klass:获取该列表的一个Model、Manager或QuerySet实例。

      ·**kwargs:查询的参数,格式应该可以被filter()接受。

    范例:

    下面的示例从MyModel中获取所有发布出来的对象:

from django.shortcuts import get_list_or_404

def my_view(request):
    my_objects = get_list_or_404(MyModel, published=True)

    这个示例等同于:

from django.http import Http404

def my_view(request):
    my_objects = list(MyModel.objects.filter(published=True))
    if not my_objects:
        raise Http404("No MyModel matches the given query.")
posted @ 2020-03-07 13:09  如心幻雨  阅读(180)  评论(0编辑  收藏  举报