Inserting values into related models from a single form post

9 views
Skip to first unread message

cd34

unread,
Sep 30, 2009, 4:25:26 PM9/30/09
to sprox
I have a model that has a related model, header and detail records.
When the record is created and the values are posted to the
controller, they are contained in request.params. I've searched the
documentation, but, can't find a way to handle this situation.

The following code was used in TurboGears2 with dbsprockets (there was
a bug in dbsprockets that removed the primary key from the passed
array, hence the copy):

provider.add('cp_ticket',values=copy.copy(kw))
cpt = copy.copy(kw)
cpt['ticket_id'] = last_insert_id()
flash('Ticket %s Entered' % cpt['ticket_id'])
provider.add('cp_ticket_detail',values=cpt)

What is the proper way to insert the header and detail records when
they are both submitted on the same form?

provider.create(cp_ticket, request.params)
provider.create(cp_ticket_detail, request_params)

Results in the row being added to cp_ticket, but, the detail record is
not submitted (probably due to the lack of the foreign key)

How do I get the last_insert_id() so that I can get the ticket number?

percious

unread,
Sep 30, 2009, 5:44:44 PM9/30/09
to sprox
It's unclear to me. Is this a sprox or a dbsprockets question.
DBSprockets is deprecated, unfortunately.

cheers.
-chris

cd34

unread,
Sep 30, 2009, 7:25:24 PM9/30/09
to sprox
sprox.

I am using Pylons + sprox and wanted to use provider.create to add the
submitted data, but, need to add it to both the header and the detail
table.

I was unable to find anything in the documentation to handle this.
While I haven't dug into the code in sprox too deeply, is there a
method for handling this?

cd34

unread,
Oct 2, 2009, 3:13:57 PM10/2/09
to sprox
Here's a self-contained controller that illustrates what I'm trying to
do.

The ticket header should be posted to cp_tickets, detail should be
posted to cp_ticket_detail referencing the ticket_id created in the
first provider.create


in the save function, how would I use sprox to do this? The code as
listed doesn't actually work, but, is there to illustrate what I'm
trying to accomplish. The cp_ticket record is created, the
cp_ticket_detail record is not.



from pylons import request, response, session, tmpl_context
from pylons.controllers.util import abort, redirect_to

from cp.lib.base import BaseController, render

import tw.forms as twf
from tw.mods.pylonshf import validate
from tw.core import WidgetsList
from tw.forms import TableForm, TextField, TextArea, RadioButtonList,
CheckBox, HiddenField, SingleSelectField
from tw.forms.validators import NotEmpty

from sqlalchemy import *
from sqlalchemy.orm import mapper, relation
from sqlalchemy import Table, ForeignKey, Column
from sqlalchemy.types import Integer, Unicode
from sqlalchemy.orm import relation, backref

from sqlalchemy.databases import mysql

from sqlalchemy.ext.declarative import declarative_base
DeclarativeBase = declarative_base()

from sprox.saormprovider import SAORMProvider
provider=SAORMProvider(meta.Session)

class cp_ticket(DeclarativeBase):
__tablename__ = 'cp_ticket'

ticket_id = Column(mysql.MSBigInteger(20, unsigned = True),
primary_key=True, autoincrement = True)
priority = Column(mysql.MSEnum('1','2','3','4','5'), default =
'3')

ticket_detail = relation('cp_ticket_detail',
order_by='cp_ticket_detail.ticket_detail_id')

class cp_ticket_detail(DeclarativeBase):
__tablename__ = 'cp_ticket_detail'

ticket_id = Column(mysql.MSBigInteger(20, unsigned = True),
ForeignKey('cp_ticket.ticket_id'), default = '0')
ticket_detail_id = Column(mysql.MSBigInteger(20, unsigned = True),
primary_key=True, autoincrement = True)
stamp = Column(mysql.MSTimeStamp, PassiveDefault
('CURRENT_TIMESTAMP'))
detail = Column(mysql.MSLongText, default = '0')


class PageForm(TableForm):
action = '/posttest/save'
submit_text = 'Submit Ticket'

class fields(WidgetsList):
priority = SingleSelectField(options=[
(1, 'Immediate'),
(2, 'High'),
(3, 'Moderate'),
(4, 'Low'),
(5, 'Inquery')], default=3, validator=NotEmpty)

detail = TextArea(label_text='Detailed Description of
problem', attrs=dict(rows=10, cols=55),validator=NotEmpty())

page_form = PageForm()

class PosttestController(BaseController):

def index(self):
tmpl_context.form = page_form
return render('/test_test.mako')

@validate(form=page_form, error_handler='index')
def save(self):
detail = request.params
provider.create(cp_ticket, request.params)
provider.create(cp_ticket_detail, request.params)
return str(request.params)

cd34

unread,
Oct 13, 2009, 11:22:56 AM10/13/09
to sprox
On Oct 2, 3:13 pm, cd34 <mcd...@gmail.com> wrote:

>     @validate(form=page_form, error_handler='index')
>     def save(self):
>         detail = request.params
>         provider.create(cp_ticket, request.params)
>         provider.create(cp_ticket_detail, request.params)
>         return str(request.params)

This is the SQLAlchemy way:

@validate(page_form, error_handler='index')
def ticketsave(self, **kw):
ticket = cp_ticket(client_id=get_client_id(),
subject=request.params['subject'], priority=request.params
['priority'], domain=request.params['domain'])
ticket.ticket_detail = [cp_ticket_detail(detail=request.params
['detail'])]
meta.Session.add(ticket)
meta.Session.flush()

Is there a way to handle this in sprox?

Chris Perkins

unread,
Oct 13, 2009, 8:49:29 PM10/13/09
to sp...@googlegroups.com
Try using request.params.mixed() in your provider calls.

cheers.
-chris
Reply all
Reply to author
Forward
0 new messages