Django:基于 'as_view()' 方法的通用视图

Django: Generic views based 'as_view()' method

我正在开发一个应用程序,其中我创建了一个通用 ListView。现在,在我的 urls.py 中定义该视图时,我从文档中了解到我需要使用 as_view() 方法,如下所示:

from django.conf.urls import patterns, include, url
from .views import BlogIndex

urlpatterns = patterns(
    '',
    url(r'^$', BlogIndex.as_view(), name="index"),
)

现在,我并没有真正理解文档中关于此方法的内容。有人可以阐明这个概念吗?

在基于 Class 的视图中,您必须调用 as_view() 函数以便 return 一个 可调用视图 需要一个 request 和 return 是 response. 在通用视图的情况下,它是请求-响应周期中的主要入口点。

as_view 是将我的 MyView class 与其 url 连接起来的函数(class 方法)。

来自 django docs:

classmethod as_view(**initkwargs)
Returns a callable view that takes a request and returns a response:

您不能像在普通的基于函数的视图中那样使用基于 class 的视图。

BlogIndex(request) # can't do this in case of CBVs

如果您希望 CBV 正常运行,以上代码无效。为此,您需要提供一个可调用的视图,然后将请求传递给它。例如:

response = MyView.as_view()(request)  # valid way

通过在我的视图上调用 as_view() 函数 class MyView 将给我一个视图,我将使用 request 参数调用该视图以启动请求-响应周期.

你的情况:

my_callable_view = BlogIndex.as_view() # returns a callable view
<function blog.views.BlogIndex>

现在,调用此函数并传递 request

 response = my_callable_view(request) # generate proper response

视图函数的格式与以前不同,因为:

  1. This view will actually be implemented as a class
  2. We will be inheriting from an existing generic view function that already does most of what we want this view function to do, rather than writing our own from scratch.
  3. Class method as_view()- this does all the work of creating an instance of the class, and making sure that the right handler methods are called for incoming HTTP requests.

参考:https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Generic_views

也许我可以尝试用伪代码编写as_view:

class ViewClass():
      #other stuff
      def as_view(self):
           return self.render(*args)

它return CBV 中的渲染函数。 所以它实际上与 path('some_path',views.some_view_function,name='some_name') 相同 当然,实际上除了render function之外还有更多的事情要做,例如验证和保存post queryDict中的内容,实际上你需要def post():来处理post,在功能上你只是 if request.method == 'POST' 它们实际上是相互的。 具体来说,as_view() 只是生成了一个整体函数,包括 if request.method =='POST': #some code 可能实际代码不是这样的,但是如果你不准备为 django 做贡献,你可以这样理解你自己的源代码。