在一个典型的请求和响应过程中,Django 接受到请求后调用路由中与 url 相匹配的视图函数,最后返回一个响应交给服务器传回客户端浏览器。视图类(class-based-view)本质上和视图函数没有任何不同,首先看看最基本的用法
# urls.py
from my_app.views import IndexView
urlpatterns = patterns('',
url(r'^$', IndexView.as_views()))
# views.py
from django.views.generic import TemplateView
class IndexView(TemplateView):
template_name = "index.html"
def get(self, request):
return self.render_to_respone({"message" : "Hello world!"})
as_view
方法实际上返回了一个函数,该函数根据 http 请求类型调用 IndexView 相应的方法:get 请求对应 get 方法,post 请求对应 post 方法。 如果方法没有定义,将会返回 HttpResponseNotAllowed 对象。通过设置视图类的 http_method_names
属性也可以限制类视图能够接受的请求类型
# 只接受 post 请求的视图类
class IndexView(TemplateView):
http_method_names = ['post']
所有的视图类属性都可以中由 as_view
重新指定, 当视图类中不包含指定的属性时,将会抛出异常。
url('^$', IndexView.as_view(template_name='other.html', http_method_names=['get']))
在 TemplateView 类中已经定义了简单的get 方法
# django/views/generic/base.py
def get(self, request, *args, **kwargs):
context = self.get_context_data(params=kwargs)
return self.render_to_response(context)
习惯上将模板数据的处理封装在 get_contxt_data
方法中,render_to_resopnse
负责调用模板并返回响应。 继承而来的 get_context_data
方法实际上只返回传递给它的关键字参数,因此重写时并不需要特意地调用父类的方法。
TemplateView 必须需指定一个模板,render_to_response
还方法需要一个 context 参数,在一些场景下并不是很好用。这时可以考虑直接继承 django.views.generic.View 类
from django import http
from django.views.generic import View
class IndexView(View):
def get(self, request):
return http.HttpResponse('Hello world!')
除了区分不同的Http请求外,使用方式和普通的视图函数并没有太大的差别。
Django 里可以通过视图函数来生成对应的url,在使用视图类时,并不能够直接通过视图类来获取 url。可以通过 url 的 name 参数来简单的解决这个问题
# urls.py
url('^$', IndexView.as_view(), name='index')
# views.py
reverse('index')
还可以在定义视图类的模块中直接引用 as_view
方法返回的函数
# urls.py
url('^$', 'my_app.views.index', name='home')
# views.py
index = IndexView.as_view()
reverse('my_app.views.index')
这样看起来就和使用普通的视图函数一样了