Django的as_view()
函数是一个将类视图转换为函数视图的工具函数,它将类视图封装为一个可调用对象,这个对象可以处理请求并返回响应。在Django中,大多数视图都是使用类视图方式定义的。但是,在某些场景下(如需要访问视图内的实例属性),使用函数视图会更加方便,因此as_view()
函数对于这种情况非常有用。下面是具体的使用方法和实例说明。
使用方法
使用as_view()
函数,需要在类视图继承View
类的基础上重载get
方法或post
方法等,具体方法根据开发需求而定。
首先在视图模块中导入as_view()
函数:
from django.views.generic import View
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
class MyView(View):
template_name = 'my_template.html'
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
def get(self, request, *args, **kwargs):
# 处理 GET 请求,返回响应
...
def post(self, request, *args, **kwargs):
# 处理 POST 请求,返回响应
...
my_view = MyView.as_view()
这个例子演示了如何使用 as_view()
将类视图 MyView
转换为函数视图。在调用as_view()
方法后,my_view
变量就成为了一个可以响应请求的函数。
通过 as_view()
转换的函数视图,处理了 GET 和 POST 请求后,会返回响应。get()
和 post()
方法中的代码会负责处理请求,并用合适的响应来响应请求。
上面例子中,使用了 method_decorator
装饰器和 login_required
装饰器来添加对用户登录的要求。dispatch()
方法能确保所有的请求都会被 login_required
装饰器要求登录,而且同时可以调用原始的 dispatch()
方法。这个功能通过调用 super().dispatch()
来实现。
示例
实例1:类视图的基本转换
首先,看一个最基本的转换类视图的代码。该类视图可以处理 GET 请求,并将 “Hello, World!” 渲染到模板中。
from django.views.generic import View
from django.http import HttpResponse
from django.shortcuts import render
class HelloWorld(View):
template_name = 'hello_world.html'
def get(self, request):
return render(request, self.template_name, {'message': 'Hello, World!'})
hello_world = HelloWorld.as_view()
这个例子中,如果我们在路由中使用了这个函数视图,那么我们将获得一个可用于处理请求的视图。如下所示:
from django.urls import path
from .views import hello_world
app_name = 'mysite'
urlpatterns = [
path('hello-world/', hello_world, name='hello_world'),
]
实例2:基于类视图的分页器
下面我们看一个更为复杂的操作。该示例定义了一个应用程序的类视图 ItemList
,它获取项目列表,并将其分成 pagesize 块。从 URL 获取当前页数,然后从项目列表中返回该页。
这个示例演示了如何在类视图中使用 Paginator
类,并让 as_view()
函数处理请求。
from django.views.generic import View
from django.shortcuts import render
from django.core.paginator import Paginator
class ItemList(View):
template_name = 'item_list.html'
queryset = range(200) # 生成 200 个数据
paginate_by = 20 # 每页显示 20 条数据
def get(self, request):
paginator = Paginator(self.queryset, self.paginate_by)
page = request.GET.get('page')
items = paginator.get_page(page)
return render(request, self.template_name, {'items': items})
item_list = ItemList.as_view()
类视图定义了一个 queryset
,其中包含多个项目,我们使用Paginator
对象将这些项目分成大小为 paginate_by
的页面。视图使用GET参数 page
来选择页码。如果用户不输入页码,将默认为页面的第一页。
在视图中,我们使用 Paginator
对象来获取指定页码 page
中的数据,然后将其中的每个项目传递给模板。模板将负责在当前页面上显示它们。