Personal tools
You are here: Home Documentation Tutorials Grok Poller Tutorial Adding Objects

Adding Objects

To add polls, we want to provide a Web form for the users.
This tutorial shows how to implement a simple polling application using Grok.
Page 7 of 14.

The view made in the last section should have a link to a new view, which displays an add form for the polls. We could code the form by hand, and fetch the results manually in the view by implementing a update() method for it; which is a view method that handles HTTP GET, POST and form parameters of the request before rendering the view, this method will be used at the Poll View section.

Grok has built-in form support, so you don't have to code them by hand, and it even includes validation and fully customizable widget support. The forms work like views, they have a context and a name, which is used to determine an URL for it. The following code (in app.py) implements a simple form for adding polls to our poll container, but it doesn't adding support poll options yet, just the question:

from zope import schema
from poller.poll import Poll

class Add(grok.AddForm):
  # Note that form_fields is a tuple
  form_fields = (
      grok.Fields(schema.TextLine(__name__='question',
                                  title=u'Question',
                                  required=True)),
      )
  # Title/header for the form template
  label = u'New poll'

  @grok.action('Add poll')
  def handle_add(self, **data):
      poll = Poll()
      self.applyData(poll, **data)
      name = poll.question
      self.context[name] = poll
      return self.redirect(self.url(self.context))

grok.AddForm is a grok.Form specialization, which handles creating new objects through a form, there is also grok.EditForm which is used for editing existing objects. At first we define form_fields class attribute, which is tells the form generator what fields to create. The form system uses Zope schema package to define these fields. The schema package includes all of the basic Python types and more, and you can use schema fields' built-in validation attributes such as min_length or max_length or you can implement your own invariants to the fields. The form system validates the fields based on that info, which allows you to create complex forms easily.

To define form buttons you use grok.action decorator on a method; that method is called when that button is pressed. The parameter for the decorator is the name of the button. In handle_add we will instantiate a new Poll object, and apply the form data to it using applyData method of the form. handle_action method accepts the form data as keyword arguments, and we use **data to catch them all in a single dictionary, which is then unpacked for the applyData method. Now we have a new poll with the input from the form applied to it, next we save it to the container as we did in the debug console; then we redirect back to the container because we don't have a view for the actual polls yet.

You can now test the form, and create new polls, even though without the poll options; which is the next step, but first we will delve a bit in to Zope interfaces.

 

Change in grok.Fields?

Posted by anil at Jan 21, 2011 02:44 AM
Working with grokproject 2.2 python 2.7, needed to change the form_fields definition to:
  form_fields = grok.Fields(schema.TextLine(
               __name__='question',
               title=u'Question',
               required=True))