Differences between revisions 13 and 14
Revision 13 as of 2012-05-04 22:52:24
Size: 11504
Comment: save to database
Revision 14 as of 2012-05-04 22:53:37
Size: 11653
Comment:
Deletions are marked like this. Additions are marked like this.
Line 301: Line 301:
 *Here is a code to save the the form.  *Here is a code to save the the form.If you need a quick guide on how to convert dates see [[http://lucasmanual.com/mywiki/PythonManual#from_string_to_datetime|#from_string_to_datetime]]

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

  • This will be the primary file where we will be working on our web application
  • Lets add our add function that will allow you to enter new addressbook.
  • Edit init.py and add the new add_route.

config.add_route('add', '/add')
  • This will add a route "add" and the url that it will use is "/add"
  • Now lets create a view that will handle our form.
  • Edit views.py and add our new "add view handler.

@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 template

  • Lets go to templates folder and create our add.pt
  • To simplify our coding we will copy an existing template and name it add.pt

cd templates
cp mytemplate.pt add.pt
  • Then replace the text:

#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.
  • Lets check if it works, and our next step will be to add the form.

add1.png

widget

requires=[

    ...

    "tw2.core",
    "tw2.forms",
    "tw2.dynforms",
    "tw2.sqla",
    "tw2.jqplugins.jqgrid",
    "formencode",
    ],
  • Then run:

python setup.py develop
  • Now edit development.ini and add this on first line:

[pipeline:main]
pipeline =
    tw2.core
    myapp

[filter:tw2.core]
use = egg:tw2.core#middleware
  • And right below change app:main

from

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

to

[app:myapp]
use = egg:...
  • Now we are ready to add the widget. Go to the view.py and add above your view

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):
    #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
    return {'widget':AddressForm(),'project':'myapp'}

* 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

  • Now that we have a form, lets create a database structure that we will save our data to. Our Addressbook table definition is a bit different then the example above. Sqlalchemy has two ways of setting database SQLAlchemy ORM vs SQLAlchemy Core. The example that uses class MyModel(Base): is SQLalchemy ORM, the sqlalchemy.Table() is SQLAlchemy Core. I believe sqlalchemy core is much simpler and easier to understand when you look at examples of how to create tables in sql language.

  • Lets edit a model.py and add the following.

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.
  • Now lets populate the database.
  • Because we renamed our app name

[app:main]
to
[app:myapp]

to support toscawidget we will need to call the initiate by adding our new app name.

initialize_myapp_db development.ini#myapp

Saving Form to Database

  • Lets import our new Addressbook model we created in model.py
  • Edit the view.py and where it says:

from .models import (
    DBSession,
    MyModel,
    )
  • Change it to:

from .models import (
    DBSession,
    MyModel,
    Addressbook,
    )
  • Now lets go into our add_view and lets see what data comes back from our controller.
  • Right before the end of if request.method=='POST you can add print request.params, this will show you what came in via the form and in what format.

  • Here is a code to save the the form.If you need a quick guide on how to convert dates see #from_string_to_datetime

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'}

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