Extending the question asked a few days ago, how can I handle 1:[1,0]
relationships?
Assume I have a master table with some information and a details table
that may or may not
have optional info, but at most one row.
In the minimal example below I can teach my form
to display this optional info, but by default, if I enter new optional
info, and move
forward and back through the masters dataset, the entered information is lost.
I added a onValueChanged handler which creates a new details row if
there is none, but
this seems not practical for two reason. First, if I enter a new
optional info and
*directly* move to the next master's row (by hitting next) and then back, the
information is still lost. Second, in my real form I have several data
controls for
the "details" table and it seems too tedious to add a event handler
for each of these
controls.
Do you have another suggestion on how to handle this situation?
Kind regards,
Karsten.
---------
#!/usr/bin/env python
# -*- coding: iso8859_15 -*-
"""Example how to model a 1:[0,1] relationship."""
version = dict(version="0.1", revision="1", stage="development")
import dabo
import dabo.dEvents as ev
dabo.ui.loadUI("wx")
import datetime
from dabo.dLocalize import _
class BizMaster(dabo.biz.dBizobj):
def initProperties(self):
self.Caption = _("BizObj for table 'master'")
self.DataSource = "master"
self.KeyField = "id"
self.AutoPopulatePK = True
self.DataStructure = (
("id", "I", True, "master", "id"),
("info", "C", False, "master", "info"),
)
self.DefaultValues = {}
self.addFrom("master")
self.addField("id")
self.addField("info")
class BizDetails(dabo.biz.dBizobj):
def initProperties(self):
self.Caption = _("BizObj for table 'details'")
self.DataSource = "details"
self.KeyField = "id"
self.AutoPopulatePK = True
self.DataStructure = (
("id", "I", True, "details", "id"),
("master_fk", "I", False, "details", "master_fk"),
("optional_info", "C", False, "details", "optional_info"),
)
self.DefaultValues = {}
self.addFrom("details")
self.addField("id")
self.addField("optional_info")
self.addField("master_fk")
class FrmOneToNullOne(dabo.ui.dForm):
def afterInit(self):
"""This is the place to insert all data controls into the form."""
self.Sizer = dabo.ui.dSizer("v")
# put a panel in the back. This enables Tab/Shift-Tab functionality
# between the controls.
panel = dabo.ui.dPanel(self)
self.Sizer.append1x(panel)
panel.Sizer = dabo.ui.dSizer("v")
# display the id
ui = self.addObject(dabo.ui.dTextBox, RegID="tbId",
DataSource="master", DataField="id", Enabled=False)
panel.Sizer.append(ui, halign="Center", border=5)
# info textbox
ui = dabo.ui.dTextBox(panel, RegID="tbInfo",
DataSource="master", DataField="info")
panel.Sizer.append(ui, halign="Center", border=5)
# optional info textbox
ui = dabo.ui.dTextBox(panel, RegID="tbOptionalInfo",
DataSource="details", DataField="optional_info")
panel.Sizer.append(ui, halign="Center", border=5)
# some buttons to navigate
hsz = dabo.ui.dSizer("h")
ui = panel.addObject(dabo.ui.dButton, Caption=_("Prev"))
ui.bindEvent(ev.Hit, lambda ev: self.prior())
hsz.append(ui)
ui = panel.addObject(dabo.ui.dButton, Caption=_("Next"))
ui.bindEvent(ev.Hit, lambda ev: self.next())
hsz.append(ui)
ui = panel.addObject(dabo.ui.dButton, Caption=_("New"))
ui.bindEvent(ev.Hit, lambda ev: self.new())
hsz.append(ui)
ui = panel.addObject(dabo.ui.dButton, Caption=_("Save"))
ui.bindEvent(ev.Hit, lambda ev: self.save())
hsz.append(ui)
ui = panel.addObject(dabo.ui.dButton, Caption=_("Delete"))
ui.bindEvent(ev.Hit, lambda ev: self.delete())
hsz.append(ui)
ui = panel.addObject(dabo.ui.dButton, Caption=_("Requery"))
ui.bindEvent(ev.Hit, lambda ev: self.requery())
hsz.append(ui)
panel.Sizer.append(hsz, halign="Center", border=5)
self.fitToSizer()
def createBizobjs(self):
"""This is the place to create all bizobjs for the application."""
conn = self.Application.getConnectionByName("myconn")
master = BizMaster(conn)
details = BizDetails(conn)
# link details to master
details.LinkField = "master_fk"
details.NewRecordOnNewParent = False
details.FillLinkFromParent = True
master.NewChildOnNew = False
master.addChild(details)
self.addBizobj(master) # the first added bizobj is the PrimaryBizobj
self.addBizobj(details)
def afterInitAll(self):
self.requery()
def onValueChanged_tbOptionalInfo(self, evt):
print "onValueChanged_tbOptionalInfo"
val = self.tbOptionalInfo.Value
print " Value=", val
biz = self.getBizobj("details")
if biz.RowCount == 0:
biz.new()
biz.setFieldVal("optional_info", val)
print " getDataSet=", biz.getDataSet()
self.update()
if __name__ == "__main__":
from dabo.dApp import dApp
from dabo.dLocalize import _
from dabo.db.dConnectInfo import dConnectInfo
app = dApp()
# Manages how preferences are saved
app.BasePrefKey = "dabo.app.minimal.FrmOneToNullOne"
dabo.settings.MDI = False
app.MainFormClass = FrmOneToNullOne
## The following information can be used in various places in your app:
app.setAppInfo("appShortName", _("FrmOneToNullOne Form"))
app.setAppInfo("appName", _("Dabo Minimal Example: FrmOneToNullOne"))
app.setAppInfo("appDescription", _("Dabo demo program
demonstrating how to handle 1:[1,0] relationships."))
## Set appVersion and appRevision from __version__.py:
app.setAppInfo("appVersion", version["version"])
app.setAppInfo("appRevision", version["revision"])
## Connections:
if version["stage"] == "development":
dbFileName = ":memory:"
connInfo = dConnectInfo(Name="myconn", DbType="SQLite",
Database=dbFileName)
app.addConnectInfo(connInfo)
## create database on the fly:
# this is uncommon for real applications, as you will usually connect to
# a populated database.
conn = app.getConnectionByName("myconn")
curs= conn.getDaboCursor()
# create tables and testdata
scriptList = """
create table master (
id integer primary key autoincrement not null,
info text
);
create table details (
id integer primary key autoincrement not null,
master_fk integer,
optional_info text
);
insert into master (id, info) values (1, 'spring');
insert into master (id, info) values (2, 'summer');
insert into master (id, info) values (3, 'autumn');
insert into details (id, master_fk, optional_info) values (1,
3, 'rainy');
insert into details (id, master_fk, optional_info) values (2,
2, 'sunny');
""".split(";")
for stmt in scriptList:
if stmt.strip():
curs.execute(stmt)
dabo.infoLog.write(stmt)
## start the app
app.setup()
app.start()
_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-users
Searchable Archives: http://leafe.com/archives/search/dabo-users
This message: http://leafe.com/archives/byMID/[EMAIL PROTECTED]