ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 02.01.2026
Просмотров: 2754
Скачиваний: 0
CHAPTER
TEN
RENDERERS
A view callable needn’t always return a Response object. If a view happens to return something which does not implement the Pyramid Response interface, Pyramid will attempt to use a renderer to construct a response. For example:
1
2
3
4
5
from pyramid.view import view_config
@view_config(renderer=’json’) def hello_world(request):
return {’content’:’Hello!’}
The above example returns a dictionary from the view callable. A dictionary does not implement the Pyramid response interface, so you might believe that this example would fail. However, since a renderer is associated with the view callable through its view configuration (in this case, using a renderer argument passed to view_config()), if the view does not return a Response object, the renderer will attempt to convert the result of the view to a response on the developer’s behalf.
Of course, if no renderer is associated with a view’s configuration, returning anything except an object which implements the Response interface will result in an error. And, if a renderer is used, whatever is returned by the view must be compatible with the particular kind of renderer used, or an error may occur during view invocation.
One exception exists: it is always OK to return a Response object, even when a renderer is configured. If a view callable returns a response object from a view that is configured with a renderer, the renderer is bypassed entirely.
Various types of renderers exist, including serialization renderers and renderers which use templating systems. See also Writing View Callables Which Use a Renderer.
107
10. RENDERERS
10.1 Writing View Callables Which Use a Renderer
As we’ve seen, view callables needn’t always return a Response object. Instead, they may return an arbitrary Python object, with the expectation that a renderer will convert that object into a response instance on your behalf. Some renderers use a templating system; other renderers use object serialization techniques.
View configuration can vary the renderer associated with a view callable via the renderer attribute. For example, this call to add_view() associates the json renderer with a view callable:
1 config.add_view(’myproject.views.my_view’, renderer=’json’)
When this configuration is added to an application, the myproject.views.my_view view callable will now use a json renderer, which renders view return values to a JSON response serialization.
Other built-in renderers include renderers which use the Chameleon templating language to render a dictionary to a response. Additional renderers can be added by developers to the system as necessary (see
Adding and Changing Renderers).
Views which use a renderer and return a non-Response value can vary non-body response attributes (such as headers and the HTTP status code) by attaching a property to the request.response attribute See
Varying Attributes of Rendered Responses.
If the view callable associated with a view configuration returns a Response object directly, any renderer associated with the view configuration is ignored, and the response is passed back to Pyramid unchanged. For example, if your view callable returns an instance of the pyramid.response.Response class as a response, no renderer will be employed.
1
2
3
4
5
6
from pyramid.response import Response from pyramid.view import view_config
@view_config(renderer=’json’) def view(request):
return Response(’OK’) # json renderer avoided
Likewise for an HTTP exception response:
1 from pyramid.httpexceptions import HTTPFound
2 from pyramid.view import view_config
3
4 @view_config(renderer=’json’)
5 def view(request):
6return HTTPFound(location=’http://example.com’) # json renderer avoided
108
10.2. BUILT-IN RENDERERS
You can of course also return the request.response attribute instead to avoid rendering:
1
2
3
4
5
6
from pyramid.view import view_config
@view_config(renderer=’json’) def view(request):
request.response.body = ’OK’
return request.response # json renderer avoided
10.2 Built-In Renderers
Several built-in renderers exist in Pyramid. These renderers can be used in the renderer attribute of view configurations.
10.2.1 string: String Renderer
The string renderer is a renderer which renders a view callable result to a string. If a view callable returns a non-Response object, and the string renderer is associated in that view’s configuration, the result will be to run the object through the Python str function to generate a string. Note that if a Unicode object is returned by the view callable, it is not str() -ified.
Here’s an example of a view that returns a dictionary. If the string renderer is specified in the configuration for this view, the view will render the returned dictionary to the str() representation of the dictionary:
1
2
3
4
5
from pyramid.view import view_config
@view_config(renderer=’string’) def hello_world(request):
return {’content’:’Hello!’}
The body of the response returned by such a view will be a string representing the str() serialization of the return value:
1 {’content’: ’Hello!’}
Views which use the string renderer can vary non-body response attributes by using the API of the request.response attribute. See Varying Attributes of Rendered Responses.
109
10. RENDERERS
10.2.2 json: JSON Renderer
The json renderer renders view callable results to JSON. It passes the return value through the json.dumps standard library function, and wraps the result in a response object. It also sets the response content-type to application/json.
Here’s an example of a view that returns a dictionary. Since the json renderer is specified in the configuration for this view, the view will render the returned dictionary to a JSON serialization:
1
2
3
4
5
from pyramid.view import view_config
@view_config(renderer=’json’) def hello_world(request):
return {’content’:’Hello!’}
The body of the response returned by such a view will be a string representing the JSON serialization of the return value:
1 ’{"content": "Hello!"}’
The return value needn’t be a dictionary, but the return value must contain values serializable by json.dumps().
You can configure a view to use the JSON renderer by naming json as the renderer argument of a view configuration, e.g. by using add_view():
1
2
3
4
config.add_view(’myproject.views.hello_world’, name=’hello’, context=’myproject.resources.Hello’, renderer=’json’)
Views which use the JSON renderer can vary non-body response attributes by using the api of the request.response attribute. See Varying Attributes of Rendered Responses.
10.3 JSONP Renderer
latex-note.png
This feature is new in Pyramid 1.1.
110
10.3. JSONP RENDERER
pyramid.renderers.JSONP is a JSONP renderer factory helper which implements a hybrid json/jsonp renderer. JSONP is useful for making cross-domain AJAX requests.
Unlike other renderers, a JSONP renderer needs to be configured at startup time “by hand”. Configure a JSONP renderer using the pyramid.config.Configurator.add_renderer() method:
from pyramid.config import Configurator
config = Configurator()
config.add_renderer(’jsonp’, JSONP(param_name=’callback’))
Once this renderer is registered via add_renderer() as above, you can use jsonp as the renderer= parameter to @view_config or pyramid.config.Configurator.add_view‘():
from pyramid.view import view_config
@view_config(renderer=’jsonp’) def myview(request):
return {’greeting’:’Hello world’}
When a view is called that uses a JSONP renderer:
•If there is a parameter in the request’s HTTP query string (aka request.GET) that matches the param_name of the registered JSONP renderer (by default, callback), the renderer will return a JSONP response.
•If there is no callback parameter in the request’s query string, the renderer will return a ‘plain’ JSON response.
Javscript library AJAX functionality will help you make JSONP requests. For example, JQuery has a getJSON function, and has equivalent (but more complicated) functionality in its ajax function.
For example (Javascript):
var api_url = ’http://api.geonames.org/timezoneJSON’ + ’?lat=38.301733840000004’ + ’&lng=-77.45869621’ +
’&username=fred’ + ’&callback=?’;
jqhxr = $.getJSON(api_url);
The string callback=? above in the the url param to the JQuery getAjax function indicates to jQuery that the query should be made as a JSONP request; the callback parameter will be automatically filled in for you and used.
111
10. RENDERERS
10.3.1 *.pt or *.txt: Chameleon Template Renderers
Two built-in renderers exist for Chameleon templates.
If the renderer attribute of a view configuration is an absolute path, a relative path or asset specification which has a final path element with a filename extension of .pt, the Chameleon ZPT renderer is used. See Chameleon ZPT Templates for more information about ZPT templates.
If the renderer attribute of a view configuration is an absolute path or a asset specification which has a final path element with a filename extension of .txt, the Chameleon text renderer is used. See Templating with Chameleon Text Templates for more information about Chameleon text templates.
The behavior of these renderers is the same, except for the engine used to render the template.
When a renderer attribute that names a template path or asset specification (e.g. myproject:templates/foo.pt or myproject:templates/foo.txt) is used, the view must return a Response object or a Python dictionary. If the view callable with an associated template returns a Python dictionary, the named template will be passed the dictionary as its keyword arguments, and the template renderer implementation will return the resulting rendered template in a response to the user. If the view callable returns anything but a Response object or a dictionary, an error will be raised.
Before passing keywords to the template, the keyword arguments derived from the dictionary returned by the view are augmented. The callable object – whatever object was used to define the view – will be automatically inserted into the set of keyword arguments passed to the template as the view keyword. If the view callable was a class, the view keyword will be an instance of that class. Also inserted into the keywords passed to the template are renderer_name (the string used in the renderer attribute of the directive), renderer_info (an object containing renderer-related information), context (the context resource of the view used to render the template), and request (the request passed to the view used to render the template). request is also available as req in Pyramid 1.3+.
Here’s an example view configuration which uses a Chameleon ZPT renderer:
1# config is an instance of pyramid.config.Configurator
2
3config.add_view(’myproject.views.hello_world’,
4 |
name=’hello’, |
5 |
context=’myproject.resources.Hello’, |
6 |
renderer=’myproject:templates/foo.pt’) |
Here’s an example view configuration which uses a Chameleon text renderer:
112
10.3. JSONP RENDERER
1
2
3
4
config.add_view(’myproject.views.hello_world’, name=’hello’, context=’myproject.resources.Hello’, renderer=’myproject:templates/foo.txt’)
Views which use a Chameleon renderer can vary response attributes by using the API of the request.response attribute. See Varying Attributes of Rendered Responses.
10.3.2 *.mak or *.mako: Mako Template Renderer
The Mako template renderer renders views using a Mako template. When used, the view must return a Response object or a Python dictionary. The dictionary items will then be used in the global template space. If the view callable returns anything but a Response object or a dictionary, an error will be raised.
When using a renderer argument to a view configuration to specify a Mako template, the value of the renderer may be a path relative to the mako.directories setting (e.g. some/template.mak) or, alternately, it may be a asset specification (e.g. apackage:templates/sometemplate.mak). Mako templates may internally inherit other Mako templates using a relative filename or a asset specification as desired.
Here’s an example view configuration which uses a relative path:
1# config is an instance of pyramid.config.Configurator
2
3config.add_view(’myproject.views.hello_world’,
4 |
name=’hello’, |
5 |
context=’myproject.resources.Hello’, |
6 |
renderer=’foo.mak’) |
It’s important to note that in Mako’s case, the ‘relative’ path name foo.mak above is not relative to the package, but is relative to the directory (or directories) configured for Mako via the mako.directories configuration file setting.
The renderer can also be provided in asset specification format. Here’s an example view configuration which uses one:
1
2
3
4
config.add_view(’myproject.views.hello_world’, name=’hello’, context=’myproject.resources.Hello’, renderer=’mypackage:templates/foo.mak’)
113