视图函数,简称视图,本质上是一个简单的Python函数,它接受Web请求并且返回Web响应。
响应的内容可以是HTML网页、重定向、404错误,XML文档或图像等任何东西。但是,无论视图本身是个什么处理逻辑,最好都返回某种响应。
视图函数的代码写在哪里也无所谓,只要它在你的Python目录下面。但是通常我们约定将视图放置在项目或应用程序目录中的名为views.py的文件中。
下面是一个返回当前日期和时间作为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
类,以及Python的datetime库。current_datetime
视图函数。current_datetime
。在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之类的错误都可以参照上面的例子。
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.shortcuts
模块中,为我们提供了很多快捷方便的类和方法,它们都很重要,使用频率很高。
render(request, template_name, context=None, content_type=None, status=None, using=None)[source]
结合一个给定的模板和一个给定的上下文字典,返回一个渲染后的HttpResponse对象。
必需参数:
可选参数:
DEFAULT_CONTENT_TYPE
设置的值。范例:
下面的例子将渲染模板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')
render_to_response(template_name, context=None, content_type=None, status=None, using=None)[source]
此功能在引入render()之前进行,不推荐,以后可能会被弃用。
redirect(to, permanent=False, args, *kwargs)[source]
根据传递进来的url参数,返回HttpResponseRedirect。
参数to可以是:
get_absolute_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')
def my_view(request): ... return redirect('/some/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)
get_object_or_404(klass, args, *kwargs)[source]
这个方法,非常有用,请一定熟记。常用于查询某个对象,找到了则进行下一步处理,如果未找到则给用户返回404页面。
在后台,Django其实是调用了模型管理器的get()方法,只会返回一个对象。不同的是,如果get()发生异常,会引发Http404异常,从而返回404页面,而不是模型的DoesNotExist异常。
必需参数:
**kwargs
:查询的参数,格式应该可以被get()接受。范例:
1.从MyModel中使用主键1来获取对象:
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异常。
get_list_or_404(klass, args, *kwargs)[source]
这其实就是get_object_or_404
多值获取版本。
在后台,返回一个给定模型管理器上filter()的结果,并将结果映射为一个列表,如果结果为空则弹出Http404异常。
必需参数:
**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.")