In the previous post, we have created our Project and Task models. Now we have to create our forms.
It is very easy to create forms with TurboGears. In this example we are going to use ToscaWidgets 1 however keep in mind that in the next major TurboGears release, TurboGears will switch to ToscaWidgets 2.
HTML forms consist of a form element and its child elements called input. In these examples, we are going to create forms in Pytho thon with the help of ToscaWidgets library and render these forms in our templates.
This is a simple example of creating a form.
# ideas/ideas/forms/project_form.py # -*- coding: utf-8 -*- """Project form module""" from tw.api import WidgetsList import tw.forms as forms from ideas.model.project import Project class ProjectForm(forms.TableForm): class fields(WidgetsList): project_name = forms.TextField(validator=forms.validators.NotEmpty) project_description = forms.TextArea(validator=forms.validators.NotEmpty) class TaskForm(forms.TableForm): class fields(WidgetsList): project_id = forms.SingleSelectField(options=Project.get_projects_for_dropdown()) task_name = forms.TextField(validator=forms.validators.NotEmpty) task_description = forms.TextArea(validator=forms.validators.NotEmpty) status = forms.RadioButtonList(options=(('open', 'Open'), ('closed', 'Closed'))) project_form = ProjectForm(action="create_project") task_form = TaskForm(action="create_task")
1) We have created two classes called ProjectForm and TaskForm inheriting ToscaWidgets’ TableForm class. When we call the project_form and task_form in our templates, it will render the form elements in a table layout.
2) In the ProjectForm, we have a text field (
<input type="text">) and a textarea (
3) In the TaskForm, we have a dropdown box with the options of all our Projects, a text input for the task name and a textarea field for the task description.
Let’s go to our controllers/root.py file. Let’s add these 4 actions there.
# these lines go before RootController class definition. from ideas.model.project import Project, Task from ideas.forms.project_form import project_form, task_form # these lines go in the RootController class. @expose('ideas.templates.new_project') def new_project(self): """ Displays the project form. """ return dict(project_form=project_form) @expose('ideas.templates.new_task') def new_task(self): """ Displays the task form. """ return dict(task_form=task_form) @expose() def create_project(self, project_name, project_description): """ Creates a project with the given name and description. Redirects to the project itself. """ project = Project(project_name=project_name, project_description=project_description) DBSession.add(project) DBSession.flush() return redirect("/show_project/%s" % project.id) @expose() def create_task(self, project_id, task_name, task_description, status): """ Creates a task for the given project with the given information. Redirects back to the project. """ task = Task(project_id=project_id, task_name=task_name, task_description=task_description, status=status) DBSession.add(task) DBSession.flush() return redirect("/show_project/%s" % project_id) @expose('ideas.templates.show_project') def show_project(self, project_id): """ Shows the project with the given id and lists its tasks as well. Redirects to the new project page if the project does not exist. """ project = DBSession.query(Project).filter_by(id=project_id).first() if not project: return redirect("/new_project") tasks = DBSession.query(Task).filter_by(project_id=project_id).all() return dict(project=project, tasks=tasks)