Python Pyramid 简明教程

Python Pyramid - View Configuration

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

The term "View Configuration" refers to the mechanism of associating a view callable (a function, method or a class) with the information of route configuration. Pyramid finds the best callable for the given URL pattern.

有三种配置 view 的方式 −

There are three ways to configure a view

  1. Using add_view() method

  2. Using @view_config() decorator

  3. Using @view_defaults () class decorator

Using add_view() Method

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

This is the simplest method of configuring a view imperatively by calling the add_view() method of the Configurator object.

此方法使用以下参数 −

This method uses the following arguments −

  1. name − The view name required to match this view callable. If name is not supplied, the empty string is used (implying the default view).

  2. context − This resource must be an object of a Python class in order for this view to be found and called. If context is not supplied, the value None, which matches any resource, is used.

  3. route_name − This value must match the name of a route configuration declaration that must match before this view will be called. If route_name is supplied, the view callable will be invoked only when the named route has matched.

  4. request_type − an interface that the request must provide in order for this view to be found and called.

  5. request_method − a string (such as "GET", "POST", "PUT", "DELETE", "HEAD", or "OPTIONS") representing an HTTP REQUEST_METHOD or a tuple containing one or more of these strings. The view will be called only when the method attribute of the request matches a supplied value.

  6. request_param − This argument can be any string or a sequence of strings. The view will only be called when the request.params dictionary has a key which matches the supplied value.

Example

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

In the following example, two functions getview() and postview() are defined and associated with two routes of the same name. These functions just return the name of the HTTP method by which they are called.

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

The getview() function is called when the URL /get is requested using GET method. Similarly, the postview() function is executed when /post path id requested by POST method.

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()

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

While the GET request can be sent by using the web browser as HTTP client, it is not possible to use it for POST request. Hence, we use the CURL command line utility.

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 方法。

As mentioned earlier, the request_method parameter can be a list of one or more HTTP methods. Let us modify the above program and define a single oneview() function that identifies the HTTP method that causes its execution.

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

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

This function is registered in the application’s configuration for all the HTTP methods.

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

Output

CURL 输出如下所示:

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

Using @view_config() Decorator

除了命令式添加视图,还可以使用 @view_config 装饰器将配置的路由与函数、方法甚至可调用的类关联起来。

Instead of adding views imperatively, the @view_config decorator can be used to associate the configured routes with a function, a method or even a callable class.

Example

如申明式配置部分所述,可以将注册的路由与函数关联起来,如下例所示:

As described in the Declarative Configuration section, a registered route can be associated with a function as in the following example −

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() 方法后,才会将视图添加到应用程序配置中。虽然消除了命令式添加视图的需要,但性能可能会略微下降。

Note that the views are added into the application configuration only after calling the scan() method. While removes the need for imperatively adding the views, the performance may be slightly slower.

Output

view_config() 装饰器还可以传递与 add_view() 方法相同的参数。可以省略所有参数。

The view_config() decorator can also be given same arguments as that of add_view() method. All arguments may be omitted.

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

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

In such a case, the function will be registered with any route name, any request method or parameters.

view_config 装饰器在可调用视图函数的定义之前放置,如以上示例所示。如果要将类用作视图可调用对象,也可以将它放在类的顶部。此类必须具有 call () 方法。

The view_config decorator is placed just before the definition of callable view function, as in the above example. It can also be put on top of a class if it is to be used as the view callable. Such a class must have a call() method.

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

In the following Pyramid application code, the MyView class is used as a callable and is decorated by the @view_config decorator.

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() 方法来添加视图,而不扫描视图配置。

Note that instead of scanning for view configurations, we can add views by explicitly calling the add_view() method.

Example

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

If the methods in a class have to be associated with different routes, separate @view_config() should be used on top of each one of them, as done in the following example. Here, we have two methods bound to two separate routes.

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()

Output

以下是 CURL 命令的输出:

Here’s the output of CURL commands −

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

Using @view_defaults() Decorator

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

view_defaults() is a class decorator. If you have to add the methods in a class as view with some common parameters and some specific parameters, the common parameters can be specified in the view_defaults() decorator on top of the class, performing configuration of each method by a separate view_config() before each one of them.

Example

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

In the following code, we have different methods responding to the same route but with different request_method. Hence we define the rout name as default, and specify the request_method in each view configuration.

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()

Output

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

The CURL commands with different HTTP requests to the server are as follows −

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