Python Pyramid - View 视图配置

术语"View Configuration(视图配置)"是指将视图可调用(函数、方法或类)与路由配置信息相关联的机制。 Pyramid 为给定的 URL 模式找到最佳可调用对象。

配置view的方式有3种 −

  • 使用 add_view() 方法

  • 使用@view_config() 装饰器

  • 使用@view_defaults()类装饰器


使用 add_view() 方法

这是通过调用 Configurator 对象的 add_view() 方法来强制配置视图的最简单方法。

此方法使用以下参数 −

  • name − 匹配此可调用视图所需的视图名称。 如果未提供名称,则使用空字符串(表示默认视图)。

  • context − 此资源必须是 Python 类的对象才能找到和调用此视图。 如果未提供上下文,则使用匹配任何资源的值 None。

  • route_name − 此值必须匹配路由配置声明的名称,该名称必须在调用此视图之前匹配。 如果提供了 route_name,则仅当命名路由匹配时才会调用可调用视图。

  • request_type − 请求必须提供的接口,以便找到和调用此视图。

  • request_method − 表示 HTTP REQUEST_METHOD 的字符串(例如"GET"、"POST"、"PUT"、"DELETE"、"HEAD"或"OPTIONS")或包含一个或多个这些字符串的元组。 仅当请求的方法属性与提供的值匹配时,才会调用视图。

  • request_param − 此参数可以是任何字符串或字符串序列。 仅当 request.params 字典具有与提供的值匹配的键时才会调用该视图。

示例

在下面的示例中,定义了两个函数 getview()postview() 并将它们与同名的两个路由相关联。 这些函数只返回调用它们的 HTTP 方法的名称。

当使用 GET 方法请求 URL /get 时,将调用 getview() 函数。 类似地,postview()函数在POST方法请求/post路径id时执行。

from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
def getview(request):
   ret=request.method
   return Response('Method: {}'.format(ret))
def postview(request):
   ret=request.method
   return Response('Method: {}'.format(ret))
   
if __name__ == '__main__':
   with Configurator() as config:
      config.add_route('getview', '/get')
      config.add_route('postview', '/post')
      config.add_view(getview, route_name='getview',request_method='GET')
      config.add_view(postview,route_name='postview', request_method='POST')
      app = config.make_wsgi_app()
      server = make_server('0.0.0.0', 6543, app)
      server.serve_forever()

虽然 GET 请求可以通过将 Web 浏览器用作 HTTP 客户端来发送,但它不能用于 POST 请求。 因此,我们使用 CURL 命令行实用程序。

C:\Users\Acer>curl localhost:6543/get
Method: GET
C:\Users\Acer>curl -d "param1=value1" -H "Content-Type: application/json" -X POST http://localhost:6543/post
Method: POST

如前所述,request_method 参数可以是一个或多个 HTTP 方法的列表。 让我们修改上面的程序并定义一个 oneview() 函数来标识导致其执行的 HTTP 方法。

def oneview(request):
   ret=request.method
   return Response('Method: {}'.format(ret))

此函数已在所有 HTTP 方法的应用程序配置中注册。

config.add_route('oneview', '/view')
config.add_view(oneview, route_name='oneview',
   request_method=['GET','POST', 'PUT', 'DELETE'])

输出

The CURL output is shown as below −

C:\Users\Acer>curl localhost:6543/view
Method: GET
C:\Users\Acer>curl -d "param1=value1" -H "Content-Type: application/json" -X POST http://localhost:6543/view
Method: POST
C:\Users\Acer>curl -d "param1=value1" -H "Content-Type: application/json" -X PUT http://localhost:6543/view
Method: PUT
C:\Users\Acer>curl -X DELETE http://localhost:6543/view
Method: DELETE

使用@view_config()装饰器

可以使用@view_config 装饰器将配置的路由与函数、方法甚至可调用类相关联,而不是强制性地添加视图。

示例

如声明性配置部分所述,已注册的路由可以与以下示例中的函数相关联 −

from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
from pyramid.view import view_config
@view_config(route_name='hello')
def hello_world(request):
   return Response('Hello World!')
if __name__ == '__main__':
   with Configurator() as config:
      config.add_route('hello', '/')
      config.scan()
      app = config.make_wsgi_app()
   server = make_server('0.0.0.0', 6543, app)
   server.serve_forever()

请注意,只有在调用 scan() 方法后,视图才会添加到应用程序配置中。 虽然不需要强制添加视图,但性能可能会稍微慢一些。

输出

view_config() 装饰器也可以被赋予与 add_view() 方法相同的参数。 所有参数都可以省略。

@view_config()
def hello_world(request):
   return Response('Hello World!')

在这种情况下,该函数将使用任何路由名称、任何请求方法或参数进行注册。

view_config 装饰器放在可调用视图函数的定义之前,如上例所示。 如果要用作可调用视图,它也可以放在类之上。 这样的类必须有一个 __call__() 方法。

在下面的 Pyramid 应用程序代码中,MyView 类用作可调用对象,并由 @view_config 装饰器装饰。

from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
from pyramid.view import view_config

@view_config(route_name='hello')
class MyView(object):
   def __init__(self, request):
      self.request = request
      
   def __call__(self):
      return Response('hello World')
      
if __name__ == '__main__':
   with Configurator() as config:
      config.add_route('hello', '/')
      #config.add_view(MyView, route_name='hello')
      config.scan()
      app = config.make_wsgi_app()
   server = make_server('0.0.0.0', 6543, app)
   server.serve_forever()

请注意,我们可以通过显式调用 add_view() 方法来添加视图,而不是扫描视图配置。

示例

如果类中的方法必须与不同的路由相关联,则应在每个方法之上使用单独的@view_config(),如下例所示。 在这里,我们有两个方法绑定到两个单独的路由。

from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
from pyramid.view import 

class MyView(object):
   def __init__(self, request):
      self.request = request
      
   @view_config(route_name='getview', request_method='GET')
   def getview(self):
      return Response('hello GET')
   @view_config(route_name='postview', request_method='POST')
   def postview(self):
      return Response('hello POST')
      
if __name__ == '__main__':
   with Configurator() as config:
      config.add_route('getview', '/get')
      config.add_route('postview', '/post')
      config.scan()
      app = config.make_wsgi_app()
   server = make_server('0.0.0.0', 6543, app)
   server.serve_forever()

输出

这是 CURL 命令的输出 −

C:\Users\Acer>curl localhost:6543/get
hello GET
C:\Users\Acer>curl -d "param1=value1" -H "Content-Type: application/json" -X POST http://localhost:6543/post
hello POST

使用@view_defaults()装饰器

view_defaults() 是类装饰器。 如果您必须将类中的方法添加为具有一些公共参数和一些特定参数的视图,公共参数可以在类顶部的 view_defaults() 装饰器中指定,在每个方法之前通过单独的 view_config() 执行每个方法的配置。

示例

在下面的代码中,我们有不同的方法响应相同的路由,但使用不同的 request_method。 因此,我们将路由名称定义为默认值,并在每个视图配置中指定 request_method

from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
from pyramid.view import view_config
from pyramid.view import view_defaults

@view_defaults(route_name='myview')
class MyView(object):
   def __init__(self, request):
      self.request = request
      
   @view_config( request_method='GET')
   def getview(self):
      return Response('hello GET')
   @view_config(request_method='POST')
   def postview(self):
      return Response('hello POST')
   @view_config(request_method='PUT')
   def putview(self):
      return Response('hello PUT')
   @view_config(request_method='DELETE')
   def delview(self):
      return Response('hello DELETE')
      
if __name__ == '__main__':
   with Configurator() as config:
      config.add_route('myview', '/view')
      config.scan()
      app = config.make_wsgi_app()
   server = make_server('0.0.0.0', 6543, app)
   server.serve_forever()

输出

向服务器发出不同HTTP请求的CURL命令如下 −

C:\Users\Acer>curl localhost:6543/view
hello GET
C:\Users\Acer>curl -d "param1=value1" -H "Content-Type: application/json" -X POST http://localhost:6543/view
hello POST
C:\Users\Acer>curl -d "param1=value1" -H "Content-Type: application/json" -X PUT http://localhost:6543/view
hello PUT
C:\Users\Acer>curl -X DELETE http://localhost:6543/view
hello DELETE