Form Tutorial ================================= This is a succinct explanation on how to use sprox's form rendering capabilities. Many of these examples will provide server code based on TurboGears2, but sprox will work with any wsgi application you have ToscaWidgets mounted in. We will assume the reader is somewhat versed in TurboGears2's :class:`tg.controllers.RestController`. Note that this is the same technology the Turbogears2 admin is based on, so this knowledge is valuable to understand how to configure the admin for your purposes. Establishing the Model Definition ----------------------------------- Let us first assume the following model for this demonstration.:: from sqlalchemy import Column, Integer, String, Date, Text, ForeignKey, Table from sqlalchemy.orm import relation from moviedemo.model import DeclarativeBase, metadata movie_directors_table = Table('movie_directors', metadata, Column('movie_id', Integer, ForeignKey('movies.movie_id'), primary_key = True), Column('director_id', Integer, ForeignKey('directors.director_id'), primary_key = True)) class Genre(DeclarativeBase): __tablename__ = "genres" genre_id = Column(Integer, primary_key=True) name = Column(String(100)) description = Column(String(200)) class Movie(DeclarativeBase): __tablename__ = "movies" movie_id = Column(Integer, primary_key=True) title = Column(String(100), nullable=False) description = Column(Text, nullable=True) genre_id = Column(Integer, ForeignKey('genres.genre_id')) genre = relation('Genre', backref='movies') release_date = Column(Date, nullable=True) class Director(DeclarativeBase): __tablename__ = "directors" movie_id = Column(Integer, primary_key=True) title = Column(String(100), nullable=False) movies = relation(Movie, secondary_join=movie_directors_table, backref="directors") The Basic Sprox Form ----------------------- Here is how we create a basic form for adding a new Movie to the database:: class NewMovieForm(AddRecordForm): __model__ = Movie new_movie_form = NewMovieForm(DBSession) And our controller code would look something like this:: @expose('moviedemo.templates.sproxdemo.movies.new') def new(self, **kw): tmpl_context.widget = new_movie_form return dict(value=kw) You may have noticed that we are passing keywords into the method. This is so that the values previously typed by the user can be displayed on failed validation. And finally, our template code::