An Introduction to Python Web Development Using the Pyramid Framework, Part 5
If you haven't read Part 4 of this series, I recommend you do that before continuing with this article. In Part 4, we discussed the startup process and configuration files.
This article covers views and renderers. Views are very important, as they're what the user sees after making a request to your application. The last part of the request process we covered in Part 4 is rendering a view.
A renderer is an object instance that can store dictionaries or custom objects and return them as a response using a certain type of renderer, such as JSON or as a simple text string.
To get started, we'll first look at the basics by learning what view callables are and how to define them. Next, we'll cover renderers in some detail.
Catch Up on All of the Articles in this Python Series
Jesse Smith has written five articles in this series. Here are the earlier installments:
View Callables
A view callable can either be a function or a class that takes, at minimum, the request object as a parameter. The view callable's primary job is to take that request and issue a Response object.
The easiest way is to define the view callable is as a function:
from pyramid.response import Response def hello_world(request): return Response('Hello world!')
Only the request object instance is passed into the function, and a Response object is returned with the text Hello world! This is great if you just want to return plain text, but chances are you'll want to return a lot more.
Defining a class isn't much more difficult. However, we need to have both an __init__ and a __call__ function:
from pyramid.response import Response class MyView(object): def __init__(self, request): self.request = request def __call__(self): return Response('hello')
With a view callable class definition, the __init__ method takes the request object as a parameter, whereas the __call__ function takes no arguments and returns the Response object.
A view callable function or class can also take the context object as a parameter:
from pyramid.response import Response class view(object): def __init__(self, context, request): self.context = context self.request = request def __call__(self): return Response('OK')
The context object is similar in most languages. The context of a request is all of the data and metadata that derives from the incoming request, either directly or indirectly.
With view callables, you don't always have to return a Response object; sometimes you might just want to share information between view callables. An object called a Renderer allows for information sharing between callables. Instead of returning a Response, the following example does a redirect:
from pyramid.httpexceptions import HTTPFound def myview(request): return HTTPFound(location='http://example.com')
The HTTPFound class is actually part of the Pyramid httpexceptions package. You can use it to raise exceptions or perform simple redirects. Using HTTPFound to raise an exception returns a 302 Found response to the user. For more information on exceptions in general, see my article "An Introduction to Object-Oriented Concepts in Python, Part 4."
You might be wondering how to handle form submissions in view callables. This is important, as most web applications need to accept form submissions. Take the simple HTML form example below:
<form method="POST" action="myview"> <div> <input type="text" name="firstname"/> </div> <div> <input type="text" name="lastname"/> </div> <input type="submit" value="Submit"/> </form>
The request object handled by the view callable will have the parameters of the form stored in an object called params. Getting the form values is much as in other languages that use their Request object to return form values:
firstname = request.params['firstname'] lastname = request.params['lastname']
When a view callable doesn't return a response object, it attempts to construct a renderer instance that returns values from a view into a string, as in the following example:
from pyramid.view import view_config @view_config(renderer='json') def hello_world(request): return {'content':'Hello!'}
In this example, a dictionary is returned from the view callable. For more information on dictionaries in general, see my article "An Introduction to Object-Oriented Concepts in Python, Part 5." What allows this example to work is the @view_config decorator, which takes a renderer object argument. A decorator is a wrapper around a function or class that accepts a function or class object as its first or only argument. There are different types of renderers; in this case, the response will be returned as a JSON string.
You can also return custom objects using a renderer:
@view_config(renderer='json') def objects(request): return [MyObject(1), MyObject(2)]
In this example, the renderer will return the objects in JSON notation.
If a view callable has both a renderer and a response, the default is to return the Response object and not the renderer instance.
Conclusion
In this article, you learned about view callables and how they're used to return a response. Sometimes a response can be a Response object or a renderer object. You also learned that the Pyramid request object has a method to hold form parameters, which can be rendered through a view callable. You can do simple redirects with the HTTPFound class.
It's important to know that different renderer types can return a string or plain text, JSON format, or custom objects. Renderers are useful for sharing information between views. There are even template renderers that render certain types of templates. You can pass keywords or arguments to these templates. You can also create your own renderers by creating and registering a renderer factory.
Part 6 of this series will cover templates in greater detail. At this stage of the series, you should be getting more comfortable with developing Pyramid web applications and the potential the framework has for handling large applications.