Addressbook

structure

You probably created your alchemy scaffold, and here is your folder structure:

myapp/
├── CHANGES.txt
├── development.ini
├── MANIFEST.in
├── myapp
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── models.py
│   ├── models.pyc
│   ├── scripts
│   │   ├── initializedb.py
│   │   ├── initializedb.pyc
│   │   ├── __init__.py
│   │   └── __init__.pyc
│   ├── static
│   │   ├── favicon.ico
│   │   ├── footerbg.png
│   │   ├── headerbg.png
│   │   ├── ie6.css
│   │   ├── middlebg.png
│   │   ├── pylons.css
│   │   ├── pyramid.png
│   │   ├── pyramid-small.png
│   │   └── transparent.gif
│   ├── templates
│   │   └── mytemplate.pt
│   ├── tests.py
│   ├── tests.pyc
│   ├── views.py
│   └── views.pyc
├── myapp.db
├── myapp.egg-info
│   ├── dependency_links.txt
│   ├── entry_points.txt
│   ├── not-zip-safe
│   ├── PKG-INFO
│   ├── requires.txt
│   ├── SOURCES.txt
│   └── top_level.txt
├── production.ini
├── README.txt
├── setup.cfg
└── setup.py

views.py

config.add_route('add', '/add')

@view_config(route_name='add', renderer='templates/add.pt')
def add_view(request):
    '''This is an add view. Here is where we define and pass any information to the template.'''
    #Code here
    return {'project':'myapp'}

add page template

cd templates
cp mytemplate.pt add.pt

#From:

Welcome to <span class="app-name">${project}</span>, an application generated by<br/>the Pyramid web application development framework.

#To:

Welcome to <span class="app-name">${project}</span>.<br/> Please add your address.

add1.png

widget

requires=[

    ...

    "tw2.core",
    "tw2.forms",
    "tw2.dynforms",
    "tw2.sqla",
    "tw2.jqplugins.jqgrid",
    "formencode",
    ],

python setup.py develop

[pipeline:main]
pipeline =
    tw2.core
    myapp

[filter:tw2.core]
use = egg:tw2.core#middleware

from

[app:main]
use = egg:...

to

[app:myapp]
use = egg:...

from tw2.forms import TableForm, TextField, CalendarDatePicker, SingleSelectField, TextArea
import tw2
#Validator
from formencode.validators import Int, NotEmpty, DateConverter, DateValidator,PostalCode,String,Email


class AddressForm(TableForm):
    title='MyApp Add Address Form'
    # This WidgetsList is just a container
    #class fields(WidgetsList):
    FirstName = TextField(validator=tw2.core.Required)
    LastName = TextField(validator=tw2.core.Required)
    MaidenLastName = TextField(validator=String)
    Email = TextField(validator=tw2.core.EmailValidator)
    Address = TextField(validator=tw2.core.Required)
    City = TextField(validator=tw2.core.Required)
    State = TextField(validator=tw2.core.Required)
    #Or you could do:
    StateChoices = (("IL"),
                     ("IN"),
                     ("MS"),
                    )
    State = SingleSelectField(options=StateChoices, validator=NotEmpty)
    ZipCode = TextField(size=5, validator=PostalCode())
    DOB = CalendarDatePicker(validator=tw2.core.DateValidator)
    GenderChoices = (("Female"),
                     ("Male"),
                    )
    Gender = SingleSelectField(options=GenderChoices)
    Description = TextArea(rows=3, cols=25)

* Now in the view.py add the following in your add_view. The first line checks if its a post request, then checks if all validators passed if it didn't pass then you need to catch the exception and send it back to the template. When all validators pass you can do what you need with the data.

import tw2.core as twc
@view_config(route_name='add', renderer='templates/add.pt')
def add_view(request):
    from myapp.widgets import AddressForm
    if request.method=='POST':
        # First, validate the posted data
        try:
            form_result = AddressForm.validate(request.POST)
        except twc.ValidationError, e:
            return {'widget': e.widget,'project':'myapp'}
        #print request
    return {'widget':AddressForm(),'project':'myapp'}

Add widget to html template

* The last part is to add our 'widget' to our template.Update your add.pt to:

   <div id="left" class="align-right">
 <p tal:content="structure widget.display()"></p>
        </div>

add_toscawidget2.png

Create database model

from sqlalchemy import (
    Column,
    Integer,
    Text,
    )

from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy.orm import (
    scoped_session,
    sessionmaker,
    )

from zope.sqlalchemy import ZopeTransactionExtension

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
Base = declarative_base()

class MyModel(Base):
    __tablename__ = 'models'
    id = Column(Integer, primary_key=True)
    name = Column(Text, unique=True)
    value = Column(Integer)

    def __init__(self, name, value):
        self.name = name
        self.value = value

#Above was already in the file

#----------Starting from here is our model data.----------------
import sqlalchemy
from sqlalchemy.orm import mapper, relation
#from addressbook.model import metadata
import time
from sqlalchemy.sql.expression import func
metadata = Base.metadata

# Normal tables may be defined and mapped at module level.
# Our Addressbook table definition.
from datetime import datetime
addressbook_table = sqlalchemy.Table("Addressbook", metadata,
    sqlalchemy.Column('Address_Sid', sqlalchemy.Integer, primary_key=True),
    sqlalchemy.Column('FirstName', sqlalchemy.Unicode(40),nullable=False),
    sqlalchemy.Column('LastName', sqlalchemy.Unicode(40),nullable=False),
    sqlalchemy.Column('MaidenLastName', sqlalchemy.Unicode(40)),
    sqlalchemy.Column('Email', sqlalchemy.Unicode(80),nullable=False),
    sqlalchemy.Column('Address', sqlalchemy.Unicode(80),nullable=False),
    sqlalchemy.Column('City', sqlalchemy.Unicode(80),nullable=False),
    sqlalchemy.Column('State', sqlalchemy.String(2),nullable=False),
    sqlalchemy.Column('ZipCode', sqlalchemy.Integer,nullable=False),
    sqlalchemy.Column('DOB', sqlalchemy.Date(),nullable=False),
    sqlalchemy.Column('Gender', sqlalchemy.Unicode(6),nullable=False),
    sqlalchemy.Column('Description', sqlalchemy.Unicode(255),nullable=False),
    sqlalchemy.Column('Created', sqlalchemy.Integer, default=int(time.time())),
    sqlalchemy.Column('Last_UpdatedDate', sqlalchemy.Date, default=datetime.now().date(), onupdate=func.now()),
    )


#This is an empty class that will become our data class
class Addressbook(object):
    def __init__(self, **kw):
        """automatically mapping attributes"""
        for key, value in kw.iteritems():
            setattr(self, key, value)
#Mapping of Table to Python Object Class
mapper(Addressbook, addressbook_table)

# Classes for reflected tables may be defined here, but the table and
# mapping itself must be done in the init_model function.

[app:main]
to
[app:myapp]

to support toscawidget we changed our app name from "main" to "myapp" so will need to call the initiate by adding our new app name.

initialize_myapp_db development.ini#myapp

Saving Form to Database

from .models import (
    DBSession,
    MyModel,
    )

from .models import (
    DBSession,
    MyModel,
    Addressbook,
    )

import tw2.core as twc
@view_config(route_name='add', renderer='templates/add.pt')
def add_view(request):
    #address_widget = AddressForm(action='saveaddress')
    from myapp.widgets import AddressForm
    #context='myapp.widget.AddressForm'
    if request.method=='POST':
        # First, validate the posted data
        try:
            form_result = AddressForm.validate(request.POST)
        except twc.ValidationError, e:
            return {'widget': e.widget,'project':'myapp'}
        #print request
        print request.params
        print request.params['FirstName']
        #Saving into a database
        address=Addressbook()
        address.FirstName = request.params['FirstName']
        address.LastName = request.params['LastName']
        address.MaidenLastName = request.params['MaidenLastName']
        address.Email = request.params['Email']
        address.Address = request.params['Address']
        address.City = request.params['City']
        address.State = request.params['State']
        address.ZipCode = request.params['ZipCode']
        import datetime,time #inproduction this should go with other import statements
        address.DOB = datetime.datetime(*time.strptime(request.params['DOB'],"%m/%d/%Y")[:3])
        address.Description = request.params['Description']
        address.Gender = request.params['Gender']
        DBSession.add(address)
    #request.session.flash("User Update Successful!")
    return {'widget':AddressForm(),'project':'myapp'}

Display Records in Datagrid

from tw2.forms import DataGrid

#The datagrid will consist of the following fields.
addressbook_grid = DataGrid(fields=[
    ('First Name', 'FirstName'),
    ('Last Name', 'LastName'),
    ('Email', 'Email')
])

@view_config(route_name='view', renderer='templates/view.pt')
def view_view(request):
    try:
        data = DBSession.query(Addressbook).all()
    except DBAPIError:
        return Response(conn_err_msg, content_type='text/plain', status_int=500)
    return {'data':data, 'project':'myapp','grid':addressbook_grid}

Add view record grid to html

cd templates
cp add.pt view.pt

 <div id="left" class="align-right">
<div><p tal:content="structure grid.display(data)"></p></div>
</div>

view_toscawidget2_datagrid.png

MyWiki: Pyramid/addressbook (last edited 2012-05-23 03:02:26 by LukaszSzybalski)