看Flask教程关于Pluggable Views的问题

2012-07-21 10:01:03 +08:00
 levon
app.add_url_rule('/users/', ShowUsers.as_view('show_users'))

后面的as_view函数的参数是具体怎么理解,看不懂教程上说的“The string you pass to that function is the name of the endpoint that view will then have.”
4478 次点击
所在节点    Flask
1 条回复
dreampuf
2012-07-21 11:53:19 +08:00
碰巧在看Flask的实现。实质是将一个Class Instance 转换为一个(或者多个,随Class 的dispatch_request方法的实现而不同)视图。
直接上代码或许比文档更直接。

@classmethod
def as_view(cls, name, *class_args, **class_kwargs):
"""Converts the class into an actual view function that can be
used with the routing system. What it does internally is generating
a function on the fly that will instanciate the :class:`View`
on each request and call the :meth:`dispatch_request` method on it.

The arguments passed to :meth:`as_view` are forwarded to the
constructor of the class.
"""
def view(*args, **kwargs):
self = view.view_class(*class_args, **class_kwargs)
return self.dispatch_request(*args, **kwargs)

if cls.decorators:
view.__name__ = name
view.__module__ = cls.__module__
for decorator in cls.decorators:
view = decorator(view)

# we attach the view class to the view function for two reasons:
# first of all it allows us to easily figure out what class based
# view this thing came from, secondly it's also used for instanciating
# the view class so you can actually replace it with something else
# for testing purposes and debugging.
view.view_class = cls
view.__name__ = name
view.__doc__ = cls.__doc__
view.__module__ = cls.__module__
view.methods = cls.methods
return view


使用举例:

class MethodView(View):
"""Like a regular class based view but that dispatches requests to
particular methods. For instance if you implement a method called
:meth:`get` it means you will response to ``'GET'`` requests and
the :meth:`dispatch_request` implementation will automatically
forward your request to that. Also :attr:`options` is set for you
automatically::

class CounterAPI(MethodView):

def get(self):
return session.get('counter', 0)

def post(self):
session['counter'] = session.get('counter', 0) + 1
return 'OK'

app.add_url_rule('/counter', view_func=CounterAPI.as_view('counter'))
"""
__metaclass__ = MethodViewType

def dispatch_request(self, *args, **kwargs):
meth = getattr(self, request.method.lower(), None)
# if the request method is HEAD and we don't have a handler for it
# retry with GET
if meth is None and request.method == 'HEAD':
meth = getattr(self, 'get', None)
assert meth is not None, 'Unimplemented method %r' % request.method
return meth(*args, **kwargs)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/43032

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX